Implemented DrawTextW as Unicode and DrawTextA as call to DrawTextW.

This commit is contained in:
Gerard Patel 2000-12-11 03:39:08 +00:00 committed by Alexandre Julliard
parent 1df0d36592
commit 158e2cb6cb
1 changed files with 82 additions and 69 deletions

View File

@ -10,6 +10,7 @@
#include "windef.h" #include "windef.h"
#include "wingdi.h" #include "wingdi.h"
#include "wine/winuser16.h" #include "wine/winuser16.h"
#include "wine/unicode.h"
#include "winbase.h" #include "winbase.h"
#include "winerror.h" #include "winerror.h"
#include "winnls.h" #include "winnls.h"
@ -29,6 +30,12 @@ DEFAULT_DEBUG_CHANNEL(text);
#define FORWARD_SLASH '/' #define FORWARD_SLASH '/'
#define BACK_SLASH '\\' #define BACK_SLASH '\\'
static const WCHAR SPACEW[] = {' ', 0};
static const WCHAR oW[] = {'o', 0};
static const WCHAR ELLIPSISW[] = {'.','.','.', 0};
static const WCHAR FORWARD_SLASHW[] = {'/', 0};
static const WCHAR BACK_SLASHW[] = {'\\', 0};
#define SWAP_INT(a,b) { int t = a; a = b; b = t; } #define SWAP_INT(a,b) { int t = a; a = b; b = t; }
static int tabstop = 8; static int tabstop = 8;
@ -36,8 +43,8 @@ static int tabwidth;
static int spacewidth; static int spacewidth;
static int prefix_offset; static int prefix_offset;
static const char *TEXT_NextLine( HDC hdc, const char *str, int *count, static const WCHAR *TEXT_NextLineW( HDC hdc, const WCHAR *str, int *count,
char *dest, int *len, int width, WORD format) WCHAR *dest, int *len, int width, WORD format)
{ {
/* Return next line of text from a string. /* Return next line of text from a string.
* *
@ -88,7 +95,7 @@ static const char *TEXT_NextLine( HDC hdc, const char *str, int *count,
if (!(format & DT_NOCLIP) || !(format & DT_NOPREFIX) || if (!(format & DT_NOCLIP) || !(format & DT_NOPREFIX) ||
(format & DT_WORDBREAK)) (format & DT_WORDBREAK))
{ {
if (!GetTextExtentPointA(hdc, &dest[j-1], 1, &size)) if (!GetTextExtentPointW(hdc, &dest[j-1], 1, &size))
return NULL; return NULL;
plen += size.cx; plen += size.cx;
} }
@ -108,7 +115,7 @@ static const char *TEXT_NextLine( HDC hdc, const char *str, int *count,
if (!(format & DT_NOCLIP) || !(format & DT_NOPREFIX) || if (!(format & DT_NOCLIP) || !(format & DT_NOPREFIX) ||
(format & DT_WORDBREAK)) (format & DT_WORDBREAK))
{ {
if (!GetTextExtentPointA(hdc, &dest[j-1], 1, &size)) if (!GetTextExtentPointW(hdc, &dest[j-1], 1, &size))
return NULL; return NULL;
plen += size.cx; plen += size.cx;
} }
@ -121,7 +128,7 @@ static const char *TEXT_NextLine( HDC hdc, const char *str, int *count,
wb_j = j; wb_j = j;
wb_count = *count; wb_count = *count;
if (!GetTextExtentPointA(hdc, &dest[lasttab], j - lasttab, &size)) if (!GetTextExtentPointW(hdc, &dest[lasttab], j - lasttab, &size))
return NULL; return NULL;
numspaces = (tabwidth - size.cx) / spacewidth; numspaces = (tabwidth - size.cx) / spacewidth;
@ -136,7 +143,7 @@ static const char *TEXT_NextLine( HDC hdc, const char *str, int *count,
if (!(format & DT_NOCLIP) || !(format & DT_NOPREFIX) || if (!(format & DT_NOCLIP) || !(format & DT_NOPREFIX) ||
(format & DT_WORDBREAK)) (format & DT_WORDBREAK))
{ {
if (!GetTextExtentPointA(hdc, &dest[j-1], 1, &size)) if (!GetTextExtentPointW(hdc, &dest[j-1], 1, &size))
return NULL; return NULL;
plen += size.cx; plen += size.cx;
} }
@ -151,7 +158,7 @@ static const char *TEXT_NextLine( HDC hdc, const char *str, int *count,
wb_i = i; wb_i = i;
wb_j = j - 1; wb_j = j - 1;
wb_count = *count; wb_count = *count;
if (!GetTextExtentPointA(hdc, &dest[j-1], 1, &size)) if (!GetTextExtentPointW(hdc, &dest[j-1], 1, &size))
return NULL; return NULL;
plen += size.cx; plen += size.cx;
} }
@ -162,7 +169,7 @@ static const char *TEXT_NextLine( HDC hdc, const char *str, int *count,
if (!(format & DT_NOCLIP) || !(format & DT_NOPREFIX) || if (!(format & DT_NOCLIP) || !(format & DT_NOPREFIX) ||
(format & DT_WORDBREAK)) (format & DT_WORDBREAK))
{ {
if (!GetTextExtentPointA(hdc, &dest[j-1], 1, &size)) if (!GetTextExtentPointW(hdc, &dest[j-1], 1, &size))
return NULL; return NULL;
plen += size.cx; plen += size.cx;
} }
@ -216,31 +223,37 @@ INT16 WINAPI DrawText16( HDC16 hdc, LPCSTR str, INT16 count, LPRECT16 rect, UINT
/*********************************************************************** /***********************************************************************
* DrawTextA (USER32.164) * DrawTextExW (USER32.166)
*/ */
INT WINAPI DrawTextA( HDC hdc, LPCSTR str, INT i_count, LPRECT rect, UINT flags ) INT WINAPI DrawTextExW( HDC hdc, LPCWSTR str, INT i_count,
LPRECT rect, UINT flags, LPDRAWTEXTPARAMS dtp )
{ {
SIZE size; SIZE size;
const char *strPtr; const WCHAR *strPtr;
static char line[1024]; static WCHAR line[1024];
int len, lh, count=i_count; int len, lh, count=i_count;
int prefix_x = 0; int prefix_x = 0;
int prefix_end = 0; int prefix_end = 0;
TEXTMETRICA tm; TEXTMETRICW tm;
int x = rect->left, y = rect->top; int x = rect->left, y = rect->top;
int width = rect->right - rect->left; int width = rect->right - rect->left;
int max_width = 0; int max_width = 0;
TRACE("%s, %d , [(%d,%d),(%d,%d)]\n", TRACE("%s, %d , [(%d,%d),(%d,%d)]\n",
debugstr_an (str, count), count, debugstr_wn (str, count), count,
rect->left, rect->top, rect->right, rect->bottom); 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 (!str) return 0; if (!str) return 0;
if (count == -1) count = strlen(str); if (count == -1) count = strlenW(str);
if (count == 0) return 0; if (count == 0) return 0;
strPtr = str; strPtr = str;
GetTextMetricsA(hdc, &tm); GetTextMetricsW(hdc, &tm);
if (flags & DT_EXTERNALLEADING) if (flags & DT_EXTERNALLEADING)
lh = tm.tmHeight + tm.tmExternalLeading; lh = tm.tmHeight + tm.tmExternalLeading;
else else
@ -251,9 +264,9 @@ INT WINAPI DrawTextA( HDC hdc, LPCSTR str, INT i_count, LPRECT rect, UINT flags
if (flags & DT_EXPANDTABS) if (flags & DT_EXPANDTABS)
{ {
GetTextExtentPointA(hdc, " ", 1, &size); GetTextExtentPointW(hdc, SPACEW, 1, &size);
spacewidth = size.cx; spacewidth = size.cx;
GetTextExtentPointA(hdc, "o", 1, &size); GetTextExtentPointW(hdc, oW, 1, &size);
tabwidth = size.cx * tabstop; tabwidth = size.cx * tabstop;
} }
@ -262,17 +275,17 @@ INT WINAPI DrawTextA( HDC hdc, LPCSTR str, INT i_count, LPRECT rect, UINT flags
do do
{ {
prefix_offset = -1; prefix_offset = -1;
strPtr = TEXT_NextLine(hdc, strPtr, &count, line, &len, width, flags); strPtr = TEXT_NextLineW(hdc, strPtr, &count, line, &len, width, flags);
if (prefix_offset != -1) if (prefix_offset != -1)
{ {
GetTextExtentPointA(hdc, line, prefix_offset, &size); GetTextExtentPointW(hdc, line, prefix_offset, &size);
prefix_x = size.cx; prefix_x = size.cx;
GetTextExtentPointA(hdc, line, prefix_offset + 1, &size); GetTextExtentPointW(hdc, line, prefix_offset + 1, &size);
prefix_end = size.cx - 1; prefix_end = size.cx - 1;
} }
if (!GetTextExtentPointA(hdc, line, len, &size)) return 0; if (!GetTextExtentPointW(hdc, line, len, &size)) return 0;
if (flags & DT_CENTER) x = (rect->left + rect->right - if (flags & DT_CENTER) x = (rect->left + rect->right -
size.cx) / 2; size.cx) / 2;
else if (flags & DT_RIGHT) x = rect->right - size.cx; else if (flags & DT_RIGHT) x = rect->right - size.cx;
@ -285,9 +298,9 @@ INT WINAPI DrawTextA( HDC hdc, LPCSTR str, INT i_count, LPRECT rect, UINT flags
if (flags & (DT_PATH_ELLIPSIS | DT_END_ELLIPSIS | DT_WORD_ELLIPSIS)) if (flags & (DT_PATH_ELLIPSIS | DT_END_ELLIPSIS | DT_WORD_ELLIPSIS))
{ {
char swapStr[sizeof(line)]; WCHAR swapStr[sizeof(line)];
char* fnameDelim = NULL; WCHAR* fnameDelim = NULL;
int totalLen = i_count >= 0 ? i_count : strlen(str); int totalLen = i_count >= 0 ? i_count : strlenW(str);
if (size.cx > width) if (size.cx > width)
{ {
@ -301,11 +314,12 @@ INT WINAPI DrawTextA( HDC hdc, LPCSTR str, INT i_count, LPRECT rect, UINT flags
if (flags & DT_PATH_ELLIPSIS) if (flags & DT_PATH_ELLIPSIS)
{ {
char* lastBkSlash = NULL; WCHAR* lastBkSlash = NULL;
char* lastFwdSlash = NULL; WCHAR* lastFwdSlash = NULL;
strncpy(line, str, totalLen); line[totalLen] = '\0'; strncpyW(line, str, totalLen);
lastBkSlash = strrchr(line, BACK_SLASH); line[totalLen] = '\0';
lastFwdSlash = strrchr(line, FORWARD_SLASH); lastBkSlash = strrchrW(line, BACK_SLASHW[0]);
lastFwdSlash = strrchrW(line, FORWARD_SLASHW[0]);
fnameDelim = lastFwdSlash ? lastFwdSlash : lastBkSlash; fnameDelim = lastFwdSlash ? lastFwdSlash : lastBkSlash;
if (lastBkSlash && lastFwdSlash) /* which is last? */ if (lastBkSlash && lastFwdSlash) /* which is last? */
if (lastBkSlash > lastFwdSlash) if (lastBkSlash > lastFwdSlash)
@ -314,25 +328,25 @@ INT WINAPI DrawTextA( HDC hdc, LPCSTR str, INT i_count, LPRECT rect, UINT flags
if (fnameDelim) if (fnameDelim)
fnameLen = &line[totalLen] - fnameDelim; fnameLen = &line[totalLen] - fnameDelim;
else else
fnameDelim = (char*)str; fnameDelim = (WCHAR*)str;
strcpy(swapStr, ELLIPSIS); strcpyW(swapStr, ELLIPSISW);
strncat(swapStr, fnameDelim, fnameLen); strncpyW(swapStr+strlenW(swapStr), fnameDelim, fnameLen);
swapStr[fnameLen+3] = '\0'; swapStr[fnameLen+3] = '\0';
strncat(swapStr, str, totalLen - fnameLen); strncpyW(swapStr+strlenW(swapStr), str, totalLen - fnameLen);
swapStr[totalLen+3] = '\0'; swapStr[totalLen+3] = '\0';
} }
else /* DT_END_ELLIPSIS | DT_WORD_ELLIPSIS */ else /* DT_END_ELLIPSIS | DT_WORD_ELLIPSIS */
{ {
strcpy(swapStr, ELLIPSIS); strcpyW(swapStr, ELLIPSISW);
strncat(swapStr, str, totalLen); strncpyW(swapStr+strlenW(swapStr), str, totalLen);
} }
TEXT_NextLine(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 */ /* if only the ELLIPSIS will fit, just let it be clipped */
len = max(3, len); len = max(3, len);
GetTextExtentPointA(hdc, line, len, &size); GetTextExtentPointW(hdc, line, len, &size);
/* FIXME: /* FIXME:
* NextLine uses GetTextExtentPoint for each character, * NextLine uses GetTextExtentPoint for each character,
@ -344,26 +358,26 @@ INT WINAPI DrawTextA( HDC hdc, LPCSTR str, INT i_count, LPRECT rect, UINT flags
while ((size.cx > width) && (len > 3)) while ((size.cx > width) && (len > 3))
{ {
line[--len] = '\0'; line[--len] = '\0';
GetTextExtentPointA(hdc, line, len, &size); GetTextExtentPointW(hdc, line, len, &size);
} }
if (fnameLen < len-3) /* some of the path will fit */ if (fnameLen < len-3) /* some of the path will fit */
{ {
/* put the ELLIPSIS between the path and filename */ /* put the ELLIPSIS between the path and filename */
strncpy(swapStr, &line[fnameLen+3], len-3-fnameLen); strncpyW(swapStr, &line[fnameLen+3], len-3-fnameLen);
swapStr[len-3-fnameLen] = '\0'; swapStr[len-3-fnameLen] = '\0';
strcat(swapStr, ELLIPSIS); strcatW(swapStr, ELLIPSISW);
strncat(swapStr, &line[3], fnameLen); strncpyW(swapStr+strlenW(swapStr), &line[3], fnameLen);
} }
else else
{ {
/* move the ELLIPSIS to the end */ /* move the ELLIPSIS to the end */
strncpy(swapStr, &line[3], len-3); strncpyW(swapStr, &line[3], len-3);
swapStr[len-3] = '\0'; swapStr[len-3] = '\0';
strcat(swapStr, ELLIPSIS); strcpyW(swapStr+strlenW(swapStr), ELLIPSISW);
} }
strncpy(line, swapStr, len); strncpyW(line, swapStr, len);
line[len] = '\0'; line[len] = '\0';
strPtr = NULL; strPtr = NULL;
} }
@ -371,7 +385,7 @@ INT WINAPI DrawTextA( HDC hdc, LPCSTR str, INT i_count, LPRECT rect, UINT flags
} }
if (!(flags & DT_CALCRECT)) if (!(flags & DT_CALCRECT))
{ {
if (!ExtTextOutA(hdc, x, y, (flags & DT_NOCLIP) ? 0 : ETO_CLIPPED, if (!ExtTextOutW(hdc, x, y, (flags & DT_NOCLIP) ? 0 : ETO_CLIPPED,
rect, line, len, NULL )) return 0; rect, line, len, NULL )) return 0;
if (prefix_offset != -1) if (prefix_offset != -1)
{ {
@ -405,6 +419,27 @@ INT WINAPI DrawTextA( HDC hdc, LPCSTR str, INT i_count, LPRECT rect, UINT flags
return y - rect->top; return y - rect->top;
} }
/***********************************************************************
* DrawTextA (USER32.164)
*/
INT WINAPI DrawTextA( HDC hdc, LPCSTR str, INT count, LPRECT rect, UINT flags )
{
WCHAR *wstr;
INT ret = 0;
DWORD wcount;
if (count == -1) count = strlen(str);
if (!count) return 0;
wcount = MultiByteToWideChar( CP_ACP, 0, str, count, NULL, 0 );
wstr = HeapAlloc(GetProcessHeap(), 0, wcount * sizeof(WCHAR));
if (wstr)
{
MultiByteToWideChar( CP_ACP, 0, str, count, wstr, wcount );
ret = DrawTextExW( hdc, wstr, wcount, rect, flags, NULL );
HeapFree(GetProcessHeap(), 0, wstr);
}
return ret;
}
/*********************************************************************** /***********************************************************************
* DrawTextW (USER32.167) * DrawTextW (USER32.167)
@ -412,19 +447,7 @@ INT WINAPI DrawTextA( HDC hdc, LPCSTR str, INT i_count, LPRECT rect, UINT flags
INT WINAPI DrawTextW( HDC hdc, LPCWSTR str, INT count, INT WINAPI DrawTextW( HDC hdc, LPCWSTR str, INT count,
LPRECT rect, UINT flags ) LPRECT rect, UINT flags )
{ {
LPSTR p; return DrawTextExW(hdc, str, count, rect, flags, NULL);
INT acount;
INT ret;
UINT codepage = CP_ACP; /* FIXME: get codepage of font charset */
acount = WideCharToMultiByte(codepage,0,str,count,NULL,0,NULL,NULL);
p = HeapAlloc( GetProcessHeap(), 0, acount );
acount = WideCharToMultiByte(codepage,0,str,count,p,acount,NULL,NULL);
if (count == -1) acount = -1;
ret = DrawTextA( hdc, p, acount, rect, flags );
HeapFree( GetProcessHeap(), 0, p );
return ret;
} }
/*********************************************************************** /***********************************************************************
@ -441,16 +464,6 @@ INT WINAPI DrawTextExA( HDC hdc, LPCSTR str, INT count,
return DrawTextA(hdc,str,count,rect,flags); return DrawTextA(hdc,str,count,rect,flags);
} }
/***********************************************************************
* DrawTextExW (USER32.166)
*/
INT WINAPI DrawTextExW( HDC hdc, LPCWSTR str, INT count,
LPRECT rect, UINT flags, LPDRAWTEXTPARAMS dtp )
{
TRACE("(%d,%p,%d,%p,0x%08x,%p)\n",hdc,str,count,rect,flags,dtp);
FIXME("ignores extended functionality\n");
return DrawTextW(hdc,str,count,rect,flags);
}
/*********************************************************************** /***********************************************************************
* TEXT_GrayString * TEXT_GrayString
* *