2002-06-13 20:36:40 +00:00
|
|
|
/*
|
|
|
|
* ReactOS kernel
|
|
|
|
* Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
*/
|
2013-03-14 20:35:39 +00:00
|
|
|
/*
|
2002-06-13 20:36:40 +00:00
|
|
|
* PROJECT: ReactOS user32.dll
|
2015-09-01 22:10:13 +00:00
|
|
|
* FILE: win32ss/user/user32/windows/font.c
|
|
|
|
* PURPOSE: Draw Text
|
2002-06-13 20:36:40 +00:00
|
|
|
* PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
|
|
|
|
* UPDATE HISTORY:
|
|
|
|
* 09-05-2001 CSH Created
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* INCLUDES ******************************************************************/
|
|
|
|
|
2005-06-19 18:06:53 +00:00
|
|
|
#include <user32.h>
|
2006-06-26 13:16:43 +00:00
|
|
|
|
2013-10-31 16:54:01 +00:00
|
|
|
DWORD WINAPI GdiGetCodePage(HDC hdc);
|
|
|
|
|
2015-09-01 22:10:13 +00:00
|
|
|
INT WINAPI DrawTextExWorker( HDC hdc, LPWSTR str, INT i_count,
|
|
|
|
LPRECT rect, UINT flags, LPDRAWTEXTPARAMS dtp );
|
2013-10-31 16:54:01 +00:00
|
|
|
|
KJK::Hyperion is proud to present "dllimport purity", another landmark commit that you should really build only after a "clean"
Disclaimer: in an uncharacteristic and daring move, I actually built, installed and booted this revision
modified tools/rbuild/backend/mingw/mingw.cpp
modified tools/rbuild/backend/mingw/modulehandler.cpp
modified tools/rbuild/module.cpp
modified tools/rbuild/project.dtd
modified tools/rbuild/rbuild.h
modified include/crt/_mingw.h
New module attribute iscrt for marking modules that implement a C runtime library
New module attribute crt for compiling and linking modules to a specific C runtime library. Can be "ntdll" (for ntdll.dll) "msvcrt" (msvcrt.dll), "crt" (statically-linked runtime), "libcntpr" (libcntpr.lib), "dll" (one of the <library> entries specifies a CRT DLL) or "static". Defaults to "msvcrt" for Win32 modules, to "static" for CRT modules themselves, and to "dll" for drivers
Define _DLL for code that compiles against a dynamically-linked CRT
Define __MINGW_IMPORT and _CRTIMP according to whether _DLL is defined. We finally use __declspec(dllimport) somewhere, anywhere (SDK headers still don't use it)
Bonus fix: actually use compiler-specific command line flags when compiling files
modified lib/3rdparty/adns/adns.rbuild
modified lib/3rdparty/libxml2/libxml2.rbuild
modified lib/3rdparty/mingw/mingw.rbuild
And for the downside: static libraries that will be linked to a module that links to the CRT dynamically have to be compiled for a dynamically-linked CRT, as well. Say it out aloud.
modified base/applications/wordpad/wordpad.rbuild
modified base/setup/usetup/usetup.rbuild
modified dll/3rdparty/dxtn/dxtn.rbuild
modified dll/3rdparty/freetype/freetype.rbuild
modified dll/3rdparty/mesa32/mesa32.rbuild
modified dll/cpl/desk/desk.rbuild
modified dll/cpl/input/input.rbuild
modified dll/cpl/intl/intl.rbuild
modified dll/cpl/joy/joy.rbuild
modified dll/cpl/main/main.rbuild
modified dll/cpl/mmsys/mmsys.rbuild
modified dll/cpl/odbccp32/odbccp32.rbuild
modified dll/cpl/powercfg/powercfg.rbuild
modified dll/cpl/sysdm/sysdm.rbuild
modified dll/cpl/telephon/telephon.rbuild
modified dll/cpl/timedate/timedate.rbuild
modified dll/cpl/usrmgr/usrmgr.rbuild
modified dll/directx/ddraw/ddraw.rbuild
modified dll/directx/dsound/dsound.rbuild
modified dll/directx/wine/wined3d/wined3d.rbuild
modified dll/nls/idndl_redist/idndl_redist.rbuild
modified dll/nls/normaliz_redist/normaliz_redist.rbuild
modified dll/shellext/deskadp/deskadp.rbuild
modified dll/shellext/deskmon/deskmon.rbuild
modified dll/shellext/fontext/fontext.rbuild
modified dll/win32/dhcpcsvc/dhcpcsvc.rbuild
modified dll/win32/dnsapi/dnsapi.rbuild
modified dll/win32/glu32/glu32.rbuild
modified dll/win32/icmp/icmp.rbuild
modified dll/win32/winmm/midimap/midimap.rbuild
modified drivers/video/displays/framebuf/framebuf.rbuild
modified drivers/video/displays/framebufacc/framebufacc.rbuild
modified drivers/video/displays/vga/vgaddi.rbuild
modified subsystems/win32/csrss/csrss.rbuild
modified subsystems/win32/csrss/win32csr/win32csr.rbuild
modified subsystems/win32/win32k/win32k.rbuild
Don't specify msvcrt explicitely as a <library> if it's going to be linked implicitely as the CRT
<library>libcntpr</library> -> crt="libcntpr"
Remove miscellaneous unused <library> entries
modified dll/win32/crtdll/crtdll.rbuild
modified dll/win32/msvcrt20/msvcrt20.rbuild
modified dll/win32/msvcrt40/msvcrt40.rbuild
modified dll/win32/msvcrt/msvcrt.rbuild
Mark CRT DLLs as CRT modules
modified dll/win32/user32/windows/font.c
modified include/reactos/wine/unicode.h
Don't redefine or redeclare CRT functions
modified dll/win32/ws2_32/include/ws2_32.h
Arch, you idiot, it's defined in <stdlib.h>
modified include/crt/ctype.h
modified include/crt/wctype.h
Don't import ctype routines that were already defined as inlines
modified include/crt/stdio.h
modified include/reactos/wine/config.h
Avoid linking to libmingwex.a if possible
modified base/applications/taskmgr/taskmgr.rbuild
modified tools/nci/nci.mak
modified tools/nci/ncitool.c
modified dll/ntdll/ntdll.rbuild
Mark ntdll module as a CRT
New "ntsys" module to import just Nt/Zw from ntdll.dll. Avoids accidentally linking to ntdll.dll's CRT when importing system calls
modified include/psdk/winternl.h
Nope, it doesn't.
modified base/applications/network/net/help.c
modified base/applications/network/net/main.c
Replace printf with puts, or GCC will do it on its own and link to the dllimport thunk for puts
modified base/applications/network/ping/ping.c
Removed broken, unnecessary workaround
modified base/shell/cmd/cmd.rbuild
Simplify cmd module
This commit dediHAPPY BIRTHDAY STEFAN GINSBERG <3 <3 <3
svn path=/trunk/; revision=37187
2008-11-04 18:16:58 +00:00
|
|
|
|
2015-09-01 22:10:13 +00:00
|
|
|
/* FUNCTIONS *****************************************************************/
|
2007-10-27 23:37:08 +00:00
|
|
|
|
2016-12-22 06:51:32 +00:00
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* TEXT_TabbedTextOut
|
|
|
|
*
|
|
|
|
* Helper function for TabbedTextOut() and GetTabbedTextExtent().
|
|
|
|
* Note: this doesn't work too well for text-alignment modes other
|
|
|
|
* than TA_LEFT|TA_TOP. But we want bug-for-bug compatibility :-)
|
|
|
|
*/
|
|
|
|
/* WINE synced 22-May-2006 */
|
|
|
|
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;
|
|
|
|
int i, j;
|
|
|
|
int start = x;
|
|
|
|
TEXTMETRICW tm;
|
|
|
|
|
|
|
|
if (!lpTabPos)
|
|
|
|
cTabStops=0;
|
|
|
|
|
|
|
|
GetTextMetricsW( hdc, &tm );
|
|
|
|
|
|
|
|
if (cTabStops == 1)
|
|
|
|
{
|
|
|
|
defWidth = *lpTabPos;
|
|
|
|
cTabStops = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
defWidth = 8 * tm.tmAveCharWidth;
|
|
|
|
}
|
|
|
|
|
|
|
|
while (count > 0)
|
|
|
|
{
|
|
|
|
RECT r;
|
|
|
|
INT x0;
|
|
|
|
x0 = x;
|
|
|
|
r.left = x0;
|
|
|
|
/* chop the string into substrings of 0 or more <tabs>
|
|
|
|
* possibly followed by 1 or more normal characters */
|
|
|
|
for (i = 0; i < count; i++)
|
|
|
|
if (lpstr[i] != '\t') break;
|
|
|
|
for (j = i; j < count; j++)
|
|
|
|
if (lpstr[j] == '\t') break;
|
|
|
|
/* get the extent of the normal character part */
|
|
|
|
GetTextExtentPointW( hdc, lpstr + i, j - i , &extent );
|
|
|
|
/* and if there is a <tab>, calculate its position */
|
|
|
|
if( i) {
|
|
|
|
/* get x coordinate for the drawing of this string */
|
|
|
|
for (; cTabStops > i; lpTabPos++, cTabStops--)
|
|
|
|
{
|
|
|
|
if( nTabOrg + abs( *lpTabPos) > x) {
|
|
|
|
if( lpTabPos[ i - 1] >= 0) {
|
|
|
|
/* a left aligned tab */
|
|
|
|
x = nTabOrg + lpTabPos[ i-1] + extent.cx;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* if tab pos is negative then text is right-aligned
|
|
|
|
* to tab stop meaning that the string extends to the
|
|
|
|
* left, so we must subtract the width of the string */
|
|
|
|
if (nTabOrg - lpTabPos[ i - 1] - extent.cx > x)
|
|
|
|
{
|
|
|
|
x = nTabOrg - lpTabPos[ i - 1];
|
|
|
|
x0 = x - extent.cx;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* if we have run out of tab stops and we have a valid default tab
|
|
|
|
* stop width then round x up to that width */
|
|
|
|
if ((cTabStops <= i) && (defWidth > 0)) {
|
|
|
|
x0 = nTabOrg + ((x - nTabOrg) / defWidth + i) * defWidth;
|
|
|
|
x = x0 + extent.cx;
|
|
|
|
} else if ((cTabStops <= i) && (defWidth < 0)) {
|
|
|
|
x = nTabOrg + ((x - nTabOrg + extent.cx) / -defWidth + i)
|
|
|
|
* -defWidth;
|
|
|
|
x0 = x - extent.cx;
|
|
|
|
}
|
|
|
|
} else
|
|
|
|
x += extent.cx;
|
|
|
|
|
|
|
|
if (fDisplayText)
|
|
|
|
{
|
|
|
|
r.top = y;
|
|
|
|
r.right = x;
|
|
|
|
r.bottom = y + extent.cy;
|
|
|
|
|
|
|
|
ExtTextOutW( hdc, x0, y, GetBkMode(hdc) == OPAQUE ? ETO_OPAQUE : 0,
|
|
|
|
&r, lpstr + i, j - i, NULL );
|
|
|
|
}
|
|
|
|
count -= j;
|
|
|
|
lpstr += j;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!extent.cy)
|
|
|
|
extent.cy = tm.tmHeight;
|
|
|
|
|
|
|
|
return MAKELONG(x - start, extent.cy);
|
|
|
|
}
|
|
|
|
|
2003-12-21 16:49:41 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
LONG
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2003-12-21 16:49:41 +00:00
|
|
|
TabbedTextOutA(
|
|
|
|
HDC hDC,
|
|
|
|
int X,
|
|
|
|
int Y,
|
|
|
|
LPCSTR lpString,
|
|
|
|
int nCount,
|
|
|
|
int nTabPositions,
|
2010-07-31 22:36:22 +00:00
|
|
|
CONST INT *lpnTabStopPositions,
|
2003-12-21 16:49:41 +00:00
|
|
|
int nTabOrigin)
|
|
|
|
{
|
|
|
|
LONG ret;
|
|
|
|
DWORD len;
|
|
|
|
LPWSTR strW;
|
2013-10-31 16:54:01 +00:00
|
|
|
UINT cp = GdiGetCodePage( hDC ); // CP_ACP
|
2003-12-21 16:49:41 +00:00
|
|
|
|
2013-10-31 16:54:01 +00:00
|
|
|
len = MultiByteToWideChar(cp, 0, lpString, nCount, NULL, 0);
|
|
|
|
if (!len) return 0;
|
2003-12-21 16:49:41 +00:00
|
|
|
strW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
|
2013-10-31 16:54:01 +00:00
|
|
|
if (!strW) return 0;
|
|
|
|
MultiByteToWideChar(cp, 0, lpString, nCount, strW, len);
|
2003-12-21 16:49:41 +00:00
|
|
|
ret = TabbedTextOutW(hDC, X, Y, strW, len, nTabPositions, lpnTabStopPositions, nTabOrigin);
|
|
|
|
HeapFree(GetProcessHeap(), 0, strW);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
LONG
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2003-12-21 16:49:41 +00:00
|
|
|
TabbedTextOutW(
|
|
|
|
HDC hDC,
|
|
|
|
int X,
|
|
|
|
int Y,
|
|
|
|
LPCWSTR lpString,
|
|
|
|
int nCount,
|
|
|
|
int nTabPositions,
|
2010-07-31 22:36:22 +00:00
|
|
|
CONST INT *lpnTabStopPositions,
|
2003-12-21 16:49:41 +00:00
|
|
|
int nTabOrigin)
|
|
|
|
{
|
|
|
|
return TEXT_TabbedTextOut(hDC, X, Y, lpString, nCount, nTabPositions, lpnTabStopPositions, nTabOrigin, TRUE);
|
|
|
|
}
|
|
|
|
|
2006-05-22 22:05:40 +00:00
|
|
|
/* WINE synced 22-May-2006 */
|
2003-07-10 21:04:32 +00:00
|
|
|
/*
|
2006-05-22 19:07:59 +00:00
|
|
|
* @implemented
|
2003-07-10 21:04:32 +00:00
|
|
|
*/
|
2002-06-13 20:36:40 +00:00
|
|
|
DWORD
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2002-06-13 20:36:40 +00:00
|
|
|
GetTabbedTextExtentA(
|
|
|
|
HDC hDC,
|
|
|
|
LPCSTR lpString,
|
|
|
|
int nCount,
|
|
|
|
int nTabPositions,
|
2010-07-31 22:36:22 +00:00
|
|
|
CONST INT *lpnTabStopPositions)
|
2002-06-13 20:36:40 +00:00
|
|
|
{
|
2006-05-22 19:07:59 +00:00
|
|
|
LONG ret;
|
2013-10-31 16:54:01 +00:00
|
|
|
UINT cp = GdiGetCodePage( hDC ); // CP_ACP
|
2013-10-31 17:45:16 +00:00
|
|
|
DWORD len;
|
|
|
|
LPWSTR strW;
|
|
|
|
|
|
|
|
len = MultiByteToWideChar(cp, 0, lpString, nCount, NULL, 0);
|
2013-10-31 16:54:01 +00:00
|
|
|
if (!len) return 0;
|
2013-10-31 17:45:16 +00:00
|
|
|
strW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
|
2013-10-31 16:54:01 +00:00
|
|
|
if (!strW) return 0;
|
|
|
|
MultiByteToWideChar(cp, 0, lpString, nCount, strW, len);
|
|
|
|
ret = GetTabbedTextExtentW(hDC, strW, len, nTabPositions, lpnTabStopPositions);
|
2006-05-22 19:07:59 +00:00
|
|
|
HeapFree(GetProcessHeap(), 0, strW);
|
|
|
|
return ret;
|
2002-06-13 20:36:40 +00:00
|
|
|
}
|
|
|
|
|
2003-07-10 21:04:32 +00:00
|
|
|
/*
|
2003-12-21 16:49:41 +00:00
|
|
|
* @implemented
|
2003-07-10 21:04:32 +00:00
|
|
|
*/
|
2002-06-13 20:36:40 +00:00
|
|
|
DWORD
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2002-06-13 20:36:40 +00:00
|
|
|
GetTabbedTextExtentW(
|
|
|
|
HDC hDC,
|
|
|
|
LPCWSTR lpString,
|
|
|
|
int nCount,
|
|
|
|
int nTabPositions,
|
2010-07-31 22:36:22 +00:00
|
|
|
CONST INT *lpnTabStopPositions)
|
2002-06-13 20:36:40 +00:00
|
|
|
{
|
2003-12-21 16:49:41 +00:00
|
|
|
return TEXT_TabbedTextOut(hDC, 0, 0, lpString, nCount, nTabPositions, lpnTabStopPositions, 0, FALSE);
|
2002-06-13 20:36:40 +00:00
|
|
|
}
|
2003-05-11 11:12:00 +00:00
|
|
|
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* DrawTextExW (USER32.@)
|
|
|
|
*
|
|
|
|
* The documentation on the extra space required for DT_MODIFYSTRING at MSDN
|
|
|
|
* is not quite complete, especially with regard to \0. We will assume that
|
|
|
|
* the returned string could have a length of up to i_count+3 and also have
|
|
|
|
* a trailing \0 (which would be 4 more than a not-null-terminated string but
|
|
|
|
* 3 more than a null-terminated string). If this is not so then increase
|
|
|
|
* the allowance in DrawTextExA.
|
|
|
|
*/
|
2006-05-22 22:05:40 +00:00
|
|
|
#define MAX_BUFFER 1024
|
2009-10-25 09:32:01 +00:00
|
|
|
/*
|
2003-07-10 21:04:32 +00:00
|
|
|
* @implemented
|
2009-10-25 09:32:01 +00:00
|
|
|
*
|
2015-04-25 09:50:09 +00:00
|
|
|
* Synced with Wine Staging 1.7.37
|
2003-07-10 21:04:32 +00:00
|
|
|
*/
|
2009-10-25 09:32:01 +00:00
|
|
|
INT WINAPI DrawTextExW( HDC hdc, LPWSTR str, INT i_count,
|
|
|
|
LPRECT rect, UINT flags, LPDRAWTEXTPARAMS dtp )
|
2003-05-11 11:12:00 +00:00
|
|
|
{
|
2015-09-01 22:10:13 +00:00
|
|
|
return DrawTextExWorker( hdc, str, i_count, rect, flags, dtp );
|
2003-05-11 11:12:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* 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.
|
2003-07-10 21:04:32 +00:00
|
|
|
*
|
2005-08-06 05:26:10 +00:00
|
|
|
* @implemented
|
2009-10-25 09:32:01 +00:00
|
|
|
*
|
2015-04-25 10:07:43 +00:00
|
|
|
* Synced with Wine Staging 1.7.37
|
2003-05-11 11:12:00 +00:00
|
|
|
*/
|
2009-10-25 09:32:01 +00:00
|
|
|
INT WINAPI DrawTextExA( HDC hdc, LPSTR str, INT count,
|
|
|
|
LPRECT rect, UINT flags, LPDRAWTEXTPARAMS dtp )
|
2003-05-11 11:12:00 +00:00
|
|
|
{
|
|
|
|
WCHAR *wstr;
|
|
|
|
WCHAR *p;
|
|
|
|
INT ret = 0;
|
|
|
|
int i;
|
|
|
|
DWORD wcount;
|
|
|
|
DWORD wmax;
|
|
|
|
DWORD amax;
|
2009-10-25 09:32:01 +00:00
|
|
|
UINT cp;
|
2003-05-11 11:12:00 +00:00
|
|
|
|
|
|
|
if (!count) return 0;
|
2009-10-25 09:32:01 +00:00
|
|
|
if (!str && count > 0) return 0;
|
2006-05-22 22:05:40 +00:00
|
|
|
if( !str || ((count == -1) && !(count = strlen(str))))
|
|
|
|
{
|
2009-10-25 09:32:01 +00:00
|
|
|
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;
|
|
|
|
|
2006-05-22 22:05:40 +00:00
|
|
|
if( flags & DT_CALCRECT)
|
|
|
|
{
|
|
|
|
rect->right = rect->left;
|
2009-10-25 09:32:01 +00:00
|
|
|
if( flags & DT_SINGLELINE)
|
|
|
|
rect->bottom = rect->top + lh;
|
|
|
|
else
|
|
|
|
rect->bottom = rect->top;
|
2006-05-22 22:05:40 +00:00
|
|
|
}
|
2009-10-25 09:32:01 +00:00
|
|
|
return lh;
|
2006-05-22 22:05:40 +00:00
|
|
|
}
|
2009-10-25 09:32:01 +00:00
|
|
|
cp = GdiGetCodePage( hdc );
|
|
|
|
wcount = MultiByteToWideChar( cp, 0, str, count, NULL, 0 );
|
2003-05-11 11:12:00 +00:00
|
|
|
wmax = wcount;
|
|
|
|
amax = count;
|
|
|
|
if (flags & DT_MODIFYSTRING)
|
|
|
|
{
|
|
|
|
wmax += 4;
|
|
|
|
amax += 4;
|
|
|
|
}
|
|
|
|
wstr = HeapAlloc(GetProcessHeap(), 0, wmax * sizeof(WCHAR));
|
|
|
|
if (wstr)
|
|
|
|
{
|
2009-10-25 09:32:01 +00:00
|
|
|
MultiByteToWideChar( cp, 0, str, count, wstr, wcount );
|
2003-05-11 11:12:00 +00:00
|
|
|
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.
|
|
|
|
*/
|
2003-12-12 20:30:02 +00:00
|
|
|
ret = DrawTextExW( hdc, wstr, wcount, rect, flags, dtp );
|
2003-05-11 11:12:00 +00:00
|
|
|
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++;
|
2009-10-25 09:32:01 +00:00
|
|
|
WideCharToMultiByte( cp, 0, wstr, wcount, str, amax, NULL, NULL );
|
2003-05-11 11:12:00 +00:00
|
|
|
}
|
|
|
|
HeapFree(GetProcessHeap(), 0, wstr);
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* DrawTextW (USER32.@)
|
2003-07-10 21:04:32 +00:00
|
|
|
*
|
|
|
|
* @implemented
|
2015-04-25 10:07:43 +00:00
|
|
|
* Synced with Wine Staging 1.7.37
|
2003-05-11 11:12:00 +00:00
|
|
|
*/
|
2009-10-25 09:32:01 +00:00
|
|
|
INT WINAPI DrawTextW( HDC hdc, LPCWSTR str, INT count, LPRECT rect, UINT flags )
|
2003-05-11 11:12:00 +00:00
|
|
|
{
|
|
|
|
DRAWTEXTPARAMS dtp;
|
|
|
|
|
|
|
|
memset (&dtp, 0, sizeof(dtp));
|
2009-10-25 09:32:01 +00:00
|
|
|
dtp.cbSize = sizeof(dtp);
|
2003-05-11 11:12:00 +00:00
|
|
|
if (flags & DT_TABSTOP)
|
|
|
|
{
|
2009-10-25 09:32:01 +00:00
|
|
|
dtp.iTabLength = (flags >> 8) & 0xff;
|
2003-05-11 11:12:00 +00:00
|
|
|
flags &= 0xffff00ff;
|
|
|
|
}
|
|
|
|
return DrawTextExW(hdc, (LPWSTR)str, count, rect, flags, &dtp);
|
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* DrawTextA (USER32.@)
|
2003-07-10 21:04:32 +00:00
|
|
|
*
|
|
|
|
* @implemented
|
2015-04-25 10:07:43 +00:00
|
|
|
* Synced with Wine Staging 1.7.37
|
2003-05-11 11:12:00 +00:00
|
|
|
*/
|
2009-10-25 09:32:01 +00:00
|
|
|
INT WINAPI DrawTextA( HDC hdc, LPCSTR str, INT count, LPRECT rect, UINT flags )
|
2003-05-11 11:12:00 +00:00
|
|
|
{
|
|
|
|
DRAWTEXTPARAMS dtp;
|
|
|
|
|
|
|
|
memset (&dtp, 0, sizeof(dtp));
|
2009-10-25 09:32:01 +00:00
|
|
|
dtp.cbSize = sizeof(dtp);
|
2003-05-11 11:12:00 +00:00
|
|
|
if (flags & DT_TABSTOP)
|
|
|
|
{
|
2009-10-25 09:32:01 +00:00
|
|
|
dtp.iTabLength = (flags >> 8) & 0xff;
|
2003-05-11 11:12:00 +00:00
|
|
|
flags &= 0xffff00ff;
|
|
|
|
}
|
|
|
|
return DrawTextExA( hdc, (LPSTR)str, count, rect, flags, &dtp );
|
2002-06-13 20:36:40 +00:00
|
|
|
}
|
2018-09-28 15:02:38 +00:00
|
|
|
|
|
|
|
/***************************************************************************
|
|
|
|
* UserLpkPSMTextOut
|
|
|
|
*
|
|
|
|
* Stripped down version of DrawText, can only draw single line text and
|
|
|
|
* Prefix underscore (only on the last found amperstand)
|
|
|
|
* only flags to be found to be of use in testing:
|
|
|
|
*
|
|
|
|
* DT_NOPREFIX - Draw the string as is it without any changes
|
|
|
|
* DT_HIDEPREFIX - Draw the string without underscore
|
|
|
|
* DT_PREFIXONLY - Draw only the underscore
|
|
|
|
*
|
|
|
|
* without any of these flags the behavior is the string being drawn without the amperstands and
|
|
|
|
* with the underscore.
|
|
|
|
*
|
|
|
|
* lpk has an equivalent function - LpkPSMTextOut
|
|
|
|
* Notes by testing:
|
|
|
|
* This function in windows doesn't check if lpString is NULL, which results a crash,
|
|
|
|
* returns seemingly random values without any logic, and ignores the DT_NOPREFIX value.
|
|
|
|
* All of these issues don't exist in the LPK version.
|
|
|
|
*
|
|
|
|
* Note: lpString does not need to be null terminated
|
|
|
|
*/
|
|
|
|
#define PREFIX 38
|
|
|
|
#define ALPHA_PREFIX 30 /* Win16: Alphabet prefix */
|
|
|
|
#define KANA_PREFIX 31 /* Win16: Katakana prefix */
|
|
|
|
|
|
|
|
INT WINAPI UserLpkPSMTextOut(HDC hdc, int x, int y, LPCWSTR lpString, int cString, DWORD dwFlags)
|
|
|
|
{
|
|
|
|
SIZE size;
|
|
|
|
TEXTMETRICW tm;
|
2018-09-28 15:10:10 +00:00
|
|
|
int len, i = 0, j = 0;
|
2018-09-28 15:02:38 +00:00
|
|
|
int prefix_count = 0, prefix_offset = -1;
|
|
|
|
LPWSTR display_str = NULL;
|
|
|
|
int prefix_x, prefix_end;
|
|
|
|
HPEN hpen;
|
|
|
|
HPEN oldPen;
|
|
|
|
|
|
|
|
if (!lpString || cString <= 0)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (dwFlags & DT_NOPREFIX) /* Windows ignores this */
|
|
|
|
{
|
2018-09-28 15:10:10 +00:00
|
|
|
TextOutW(hdc, x, y, lpString, cString);
|
2018-09-28 15:02:38 +00:00
|
|
|
GetTextExtentPointW(hdc, lpString, cString, &size);
|
|
|
|
return size.cx;
|
|
|
|
}
|
|
|
|
|
|
|
|
display_str = HeapAlloc(GetProcessHeap(), 0, (cString + 1) * sizeof(WCHAR));
|
|
|
|
|
|
|
|
if (!display_str)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
while (i < cString)
|
|
|
|
{
|
|
|
|
if (lpString[i] == PREFIX || (iswspace(lpString[i]) && lpString[i] != L' '))
|
|
|
|
{
|
|
|
|
if (i < cString - 1 && lpString[i + 1] == PREFIX)
|
|
|
|
display_str[j++] = lpString[i++];
|
|
|
|
else
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
display_str[j++] = lpString[i++];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
display_str[j] = L'\0';
|
|
|
|
len = wcslen(display_str);
|
|
|
|
|
|
|
|
if (!(dwFlags & DT_PREFIXONLY))
|
2018-09-28 15:10:10 +00:00
|
|
|
TextOutW(hdc, x, y, display_str, len);
|
2018-09-28 15:02:38 +00:00
|
|
|
|
|
|
|
if (!(dwFlags & DT_HIDEPREFIX))
|
|
|
|
{
|
|
|
|
|
|
|
|
for (i = 0; i < cString - 1; i++)
|
|
|
|
{
|
|
|
|
if (lpString[i] == PREFIX && lpString[i + 1] != PREFIX)
|
|
|
|
{
|
|
|
|
prefix_offset = i - prefix_count;
|
|
|
|
prefix_count++;
|
|
|
|
}
|
|
|
|
else if (lpString[i] == PREFIX && lpString[i + 1] == PREFIX)
|
|
|
|
{
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
GetTextMetricsW(hdc, &tm);
|
|
|
|
|
|
|
|
if (prefix_offset != -1)
|
|
|
|
{
|
|
|
|
GetTextExtentPointW(hdc, display_str, prefix_offset, &size);
|
|
|
|
prefix_x = x + size.cx;
|
|
|
|
GetTextExtentPointW(hdc, display_str, prefix_offset + 1, &size);
|
|
|
|
prefix_end = x + size.cx - 1;
|
|
|
|
hpen = CreatePen(PS_SOLID, 1, GetTextColor(hdc));
|
|
|
|
oldPen = SelectObject(hdc, hpen);
|
|
|
|
MoveToEx(hdc, prefix_x, y + tm.tmAscent + 1, NULL);
|
|
|
|
LineTo(hdc, prefix_end, y + tm.tmAscent + 1);
|
|
|
|
SelectObject(hdc, oldPen);
|
|
|
|
DeleteObject(hpen);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
GetTextExtentPointW(hdc, display_str, len + 1, &size);
|
|
|
|
HeapFree(GetProcessHeap(), 0, display_str);
|
|
|
|
|
|
|
|
return size.cx;
|
|
|
|
}
|