ReactOS  0.4.14-dev-554-g2f8d847
text.c File Reference
#include <assert.h>
#include "wine/test.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "winerror.h"
#include "winnls.h"
Include dependency graph for text.c:

Go to the source code of this file.

Macros

#define MODIFIED(rect)   (rect.left == 10 && rect.right != 100 && rect.top == 10 && rect.bottom != 100)
 
#define EMPTY(rect)   (rect.left == rect.right && rect.bottom == rect.top)
 
#define TABTEST(tabval, tabcount, string, _exp)
 

Functions

static void test_DrawTextCalcRect (void)
 
static void strfmt (const char *str, char *strout)
 
static void test_TabbedText (void)
 
static void test_DrawState (void)
 
static void test_CharToOem_OemToChar (void)
 
 START_TEST (text)
 

Macro Definition Documentation

◆ EMPTY

#define EMPTY (   rect)    (rect.left == rect.right && rect.bottom == rect.top)

Definition at line 32 of file text.c.

◆ MODIFIED

#define MODIFIED (   rect)    (rect.left == 10 && rect.right != 100 && rect.top == 10 && rect.bottom != 100)

Definition at line 31 of file text.c.

◆ TABTEST

#define TABTEST (   tabval,
  tabcount,
  string,
  _exp 
)
Value:
{ int i; char strdisp[64];\
for(i=0;i<8;i++) tabs[i]=(i+1)*(tabval); \
extent = GetTabbedTextExtentA( hdc, string, strlen( string), (tabcount), tabs); \
strfmt( string, strdisp); \
/* trace( "Extent is %08lx\n", extent); */\
ok( extent == _exp, "Test case \"%s\". Text extent is 0x%x, expected 0x%x tab %d tabcount %d\n", \
strdisp, extent, _exp, tabval, tabcount); \
} \
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
DWORD WINAPI GetTabbedTextExtentA(_In_ HDC hdc, _In_reads_(chCount) LPCSTR lpString, _In_ int chCount, _In_ int nTabPositions, _In_reads_opt_(nTabPositions) CONST INT *lpnTabStopPositions)
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
HDC hdc
Definition: main.c:9

Definition at line 628 of file text.c.

Function Documentation

◆ START_TEST()

START_TEST ( text  )

Definition at line 839 of file text.c.

840 {
841  test_TabbedText();
843  test_DrawState();
845 }
static void test_DrawTextCalcRect(void)
Definition: text.c:34
static void test_DrawState(void)
Definition: text.c:707
static void test_TabbedText(void)
Definition: text.c:639
static void test_CharToOem_OemToChar(void)
Definition: text.c:747

◆ strfmt()

static void strfmt ( const char str,
char strout 
)
static

Definition at line 617 of file text.c.

618 {
619  unsigned int i,j ;
620  for(i=0,j=0;i<=strlen(str);i++,j++)
621  if((strout[j]=str[i])=='\t') {
622  strout[j++]='\\';
623  strout[j]='t';
624  }
625 }
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
const WCHAR * str
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250

Referenced by main().

◆ test_CharToOem_OemToChar()

static void test_CharToOem_OemToChar ( void  )
static

Definition at line 747 of file text.c.

748 {
749  static const WCHAR helloWorldW[] = {'H','e','l','l','o',' ','W','o','r','l','d',0};
750  static const WCHAR emptyW[] = {0};
751  static const char helloWorld[] = "Hello World";
752  static const struct
753  {
754  BOOL src, dst, ret;
755  }
756  tests[] =
757  {
758  { FALSE, FALSE, FALSE },
759  { TRUE, FALSE, FALSE },
760  { FALSE, TRUE, FALSE },
761  { TRUE, TRUE, TRUE },
762  };
763  BOOL ret;
764  int i;
765  char oem;
766  WCHAR uni, expect;
767 
768  for (i = 0; i < ARRAY_SIZE(tests); i++)
769  {
770  const char *expected = tests[i].ret ? helloWorld : "";
771  const char *src = tests[i].src ? helloWorld : NULL;
772  char buf[64], *dst = tests[i].dst ? buf : NULL;
773 
774  memset(buf, 0, sizeof(buf));
775  ret = CharToOemA(src, dst);
776  ok(ret == tests[i].ret, "test %d: expected %d, got %d\n", i, tests[i].ret, ret);
777  ok(!strcmp(buf, expected), "test %d: got '%s'\n", i, buf);
778 
779  memset(buf, 0, sizeof(buf));
780  ret = CharToOemBuffA(src, dst, sizeof(helloWorld));
781  ok(ret == tests[i].ret, "test %d: expected %d, got %d\n", i, tests[i].ret, ret);
782  ok(!strcmp(buf, expected), "test %d: got '%s'\n", i, buf);
783 
784  memset(buf, 0, sizeof(buf));
785  ret = OemToCharA(src, dst);
786  ok(ret == tests[i].ret, "test %d: expected %d, got %d\n", i, tests[i].ret, ret);
787  ok(!strcmp(buf, expected), "test %d: got '%s'\n", i, buf);
788 
789  memset(buf, 0, sizeof(buf));
790  ret = OemToCharBuffA(src, dst, sizeof(helloWorld));
791  ok(ret == tests[i].ret, "test %d: expected %d, got %d\n", i, tests[i].ret, ret);
792  ok(!strcmp(buf, expected), "test %d: got '%s'\n", i, buf);
793  }
794 
795  for (i = 0; i < ARRAY_SIZE(tests); i++)
796  {
797  const char *expected = tests[i].ret ? helloWorld : "";
798  const WCHAR *src = tests[i].src ? helloWorldW : NULL;
799  char buf[64], *dst = tests[i].dst ? buf : NULL;
800 
801  memset(buf, 0, sizeof(buf));
802  ret = CharToOemW(src, dst);
803  ok(ret == tests[i].ret, "test %d: expected %d, got %d\n", i, tests[i].ret, ret);
804  ok(!strcmp(buf, expected), "test %d: got '%s'\n", i, buf);
805 
806  memset(buf, 0, sizeof(buf));
807  ret = CharToOemBuffW(src, dst, ARRAY_SIZE(helloWorldW));
808  ok(ret == tests[i].ret, "test %d: expected %d, got %d\n", i, tests[i].ret, ret);
809  ok(!strcmp(buf, expected), "test %d: got '%s'\n", i, buf);
810  }
811 
812  for (i = 0; i < ARRAY_SIZE(tests); i++)
813  {
814  const WCHAR *expected = tests[i].ret ? helloWorldW : emptyW;
815  const char *src = tests[i].src ? helloWorld : NULL;
816  WCHAR buf[64], *dst = tests[i].dst ? buf : NULL;
817 
818  memset(buf, 0, sizeof(buf));
819  ret = OemToCharW(src, dst);
820  ok(ret == tests[i].ret, "test %d: expected %d, got %d\n", i, tests[i].ret, ret);
821  ok(!lstrcmpW(buf, expected), "test %d: got '%s'\n", i, wine_dbgstr_w(buf));
822 
823  memset(buf, 0, sizeof(buf));
824  ret = OemToCharBuffW(src, dst, sizeof(helloWorld));
825  ok(ret == tests[i].ret, "test %d: expected %d, got %d\n", i, tests[i].ret, ret);
826  ok(!lstrcmpW(buf, expected), "test %d: got '%s'\n", i, wine_dbgstr_w(buf));
827  }
828 
829  for (i = 0; i < 0x100; i++)
830  {
831  oem = i;
832  ret = OemToCharBuffW( &oem, &uni, 1 );
833  ok( ret, "%02x: returns FALSE\n", i );
835  ok( uni == expect, "%02x: got %04x expected %04x\n", i, uni, expect );
836  }
837 }
BOOL WINAPI CharToOemBuffW(LPCWSTR s, LPSTR d, DWORD len)
Definition: text.c:229
struct param_test tests[]
#define TRUE
Definition: types.h:120
#define MB_USEGLYPHCHARS
Definition: unicode.h:42
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
char * wine_dbgstr_w(const wchar_t *wstr)
Definition: atltest.h:87
int WINAPI lstrcmpW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:170
#define MB_PRECOMPOSED
Definition: winnls.h:278
BOOL WINAPI OemToCharW(LPCSTR s, LPWSTR d)
Definition: text.c:457
BOOL WINAPI OemToCharA(LPCSTR s, LPSTR d)
Definition: text.c:418
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
unsigned int BOOL
Definition: ntddk_ex.h:94
smooth NULL
Definition: ftsmooth.c:416
BOOL WINAPI CharToOemW(LPCWSTR s, LPSTR d)
Definition: text.c:242
__wchar_t WCHAR
Definition: xmlstorage.h:180
BOOL WINAPI CharToOemBuffA(LPCSTR s, LPSTR d, DWORD len)
Definition: text.c:209
int ret
GLenum src
Definition: glext.h:6340
BOOL WINAPI CharToOemA(LPCSTR s, LPSTR d)
Definition: text.c:198
static const WCHAR emptyW[]
Definition: navigate.c:40
#define ARRAY_SIZE(a)
Definition: main.h:24
#define ok(value,...)
Definition: atltest.h:57
GLenum GLenum dst
Definition: glext.h:6340
#define expect(expected, got)
Definition: combo.c:36
#define MultiByteToWideChar
Definition: compat.h:100
BOOL WINAPI OemToCharBuffA(LPCSTR s, LPSTR d, DWORD len)
Definition: text.c:427
BOOL WINAPI OemToCharBuffW(LPCSTR s, LPWSTR d, DWORD len)
Definition: text.c:447
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
#define memset(x, y, z)
Definition: compat.h:39
#define CP_OEMCP
Definition: winnls.h:228
BOOL expected
Definition: store.c:2063

Referenced by START_TEST().

◆ test_DrawState()

static void test_DrawState ( void  )
static

Definition at line 707 of file text.c.

708 {
709  static const char text[] = "Sample text string";
710  HWND hwnd;
711  HDC hdc;
712  BOOL ret;
713 
714  hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP,
715  0, 0, 200, 200, 0, 0, 0, NULL);
716  assert(hwnd);
717 
718  hdc = GetDC(hwnd);
719  assert(hdc);
720 
721  SetLastError(0xdeadbeef);
723  0, 0, 10, 10, DST_TEXT);
724  ok(ret, "DrawState error %u\n", GetLastError());
725 
726  SetLastError(0xdeadbeef);
728  0, 0, 10, 10, DST_TEXT);
729  ok(ret, "DrawState error %u\n", GetLastError());
730 
731  SetLastError(0xdeadbeef);
733  0, 0, 10, 10, DST_TEXT);
734  ok(!ret || broken(ret) /* win98 */, "DrawState succeeded\n");
735  ok(GetLastError() == 0xdeadbeef, "not expected error %u\n", GetLastError());
736 
737  SetLastError(0xdeadbeef);
739  0, 0, 10, 10, DST_TEXT);
740  ok(!ret || broken(ret) /* win98 */, "DrawState succeeded\n");
741  ok(GetLastError() == 0xdeadbeef, "not expected error %u\n", GetLastError());
742 
743  ReleaseDC(hwnd, hdc);
745 }
HGDIOBJ WINAPI GetStockObject(_In_ int)
const DOCKBAR PVOID HWND HWND * hwnd
Definition: tooldock.h:22
HDC WINAPI GetDC(_In_opt_ HWND)
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
const WCHAR * text
Definition: package.c:1827
static HDC
Definition: imagelist.c:92
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
#define DST_TEXT
Definition: winuser.h:513
BOOL WINAPI DestroyWindow(_In_ HWND)
unsigned int BOOL
Definition: ntddk_ex.h:94
int WINAPI ReleaseDC(_In_opt_ HWND, _In_ HDC)
smooth NULL
Definition: ftsmooth.c:416
LONG_PTR LPARAM
Definition: windef.h:208
#define assert(e)
Definition: text.c:47
#define SetLastError(x)
Definition: compat.h:417
int ret
HDC hdc
Definition: main.c:9
#define DKGRAY_BRUSH
Definition: wingdi.h:896
#define broken(x)
Definition: _sntprintf.h:21
#define ok(value,...)
Definition: atltest.h:57
#define WS_POPUP
Definition: pedump.c:616
BOOL WINAPI DrawStateA(_In_ HDC, _In_opt_ HBRUSH, _In_opt_ DRAWSTATEPROC, _In_ LPARAM, _In_ WPARAM, _In_ int, _In_ int, _In_ int, _In_ int, _In_ UINT)
HWND WINAPI CreateWindowExA(_In_ DWORD dwExStyle, _In_opt_ LPCSTR lpClassName, _In_opt_ LPCSTR lpWindowName, _In_ DWORD dwStyle, _In_ int X, _In_ int Y, _In_ int nWidth, _In_ int nHeight, _In_opt_ HWND hWndParent, _In_opt_ HMENU hMenu, _In_opt_ HINSTANCE hInstance, _In_opt_ LPVOID lpParam)

Referenced by START_TEST().

◆ test_DrawTextCalcRect()

static void test_DrawTextCalcRect ( void  )
static

Definition at line 34 of file text.c.

35 {
36  HWND hwnd;
37  HDC hdc;
38  HFONT hFont, hOldFont;
39  LOGFONTA lf;
40  static CHAR text[] = "Example text for testing DrawText in "
41  "MM_HIENGLISH mode";
42  static WCHAR textW[] = {'W','i','d','e',' ','c','h','a','r',' ',
43  's','t','r','i','n','g','\0'};
44  static CHAR emptystring[] = "";
45  static WCHAR emptystringW[] = { 0 };
46  static CHAR wordbreak_text[] = "line1 line2";
47  static WCHAR wordbreak_textW[] = {'l','i','n','e','1',' ','l','i','n','e','2',0};
48  static char tabstring[] = "one\ttwo";
49  INT textlen, textheight, heightcheck;
50  RECT rect = { 0, 0, 100, 0 }, rect2;
51  BOOL ret;
52  DRAWTEXTPARAMS dtp;
53  BOOL conform_xp = TRUE;
54 
55  /* Initialization */
56  hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP,
57  0, 0, 200, 200, 0, 0, 0, NULL);
58  ok(hwnd != 0, "CreateWindowExA error %u\n", GetLastError());
59  hdc = GetDC(hwnd);
60  ok(hdc != 0, "GetDC error %u\n", GetLastError());
61  trace("hdc %p\n", hdc);
62  textlen = lstrlenA(text);
63 
64  /* LOGFONT initialization */
65  memset(&lf, 0, sizeof(lf));
68  lf.lfWeight = FW_DONTCARE;
69  lf.lfHeight = 0; /* mapping mode dependent */
71  lstrcpyA(lf.lfFaceName, "Arial");
72 
73  /* DrawText in MM_HIENGLISH with DT_CALCRECT */
75  lf.lfHeight = 100 * 9 / 72; /* 9 point */
77  ok(hFont != 0, "CreateFontIndirectA error %u\n",
78  GetLastError());
79  hOldFont = SelectObject(hdc, hFont);
80 
81  textheight = DrawTextA(hdc, text, textlen, &rect, DT_CALCRECT |
83  DT_NOPREFIX);
84  ok( textheight, "DrawTextA error %u\n", GetLastError());
85 
86  trace("MM_HIENGLISH rect.bottom %d\n", rect.bottom);
87  ok(rect.bottom < 0, "In MM_HIENGLISH, DrawText with "
88  "DT_CALCRECT should return a negative rectangle bottom. "
89  "(bot=%d)\n", rect.bottom);
90 
91  SelectObject(hdc, hOldFont);
93  ok( ret, "DeleteObject error %u\n", GetLastError());
94 
95 
96  /* DrawText in MM_TEXT with DT_CALCRECT */
99  LOGPIXELSY), 72); /* 9 point */
100  hFont = CreateFontIndirectA(&lf);
101  ok(hFont != 0, "CreateFontIndirectA error %u\n",
102  GetLastError());
103  hOldFont = SelectObject(hdc, hFont);
104 
105  textheight = DrawTextA(hdc, text, textlen, &rect, DT_CALCRECT |
107  DT_NOPREFIX);
108  ok( textheight, "DrawTextA error %u\n", GetLastError());
109 
110  trace("MM_TEXT rect.bottom %d\n", rect.bottom);
111  ok(rect.bottom > 0, "In MM_TEXT, DrawText with DT_CALCRECT "
112  "should return a positive rectangle bottom. (bot=%d)\n",
113  rect.bottom);
114 
115  /* empty or null text should in some cases calc an empty rectangle */
116 
117  SetRect( &rect, 10,10, 100, 100);
118  heightcheck = textheight = DrawTextExA(hdc, text, 0, &rect, DT_CALCRECT, NULL );
119  ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
120  "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
121  ok(textheight==0,"Got textheight from DrawTextExA\n");
122 
123  SetRect( &rect, 10,10, 100, 100);
124  textheight = DrawTextA(hdc, text, 0, &rect, DT_CALCRECT);
125  ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
126  "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
127  if (conform_xp)
128  ok(textheight==0,"Got textheight from DrawTextA\n");
129  ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
130 
131  SetRect( &rect, 10,10, 100, 100);
132  SetLastError( 0);
133  heightcheck = textheight = DrawTextExA(hdc, emptystring, -1, &rect, DT_CALCRECT, NULL );
134  ok(EMPTY(rect), "rectangle should be empty got %s\n", wine_dbgstr_rect(&rect));
135  ok(textheight!=0,"Failed to get textheight from DrawTextExA\n");
136 
137  SetRect( &rect, 10,10, 100, 100);
138  textheight = DrawTextA(hdc, emptystring, -1, &rect, DT_CALCRECT);
139  ok(EMPTY(rect), "rectangle should be empty got %s\n", wine_dbgstr_rect(&rect));
140  ok(textheight!=0,"Failed to get textheight from DrawTextA\n");
141  ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
142 
143  SetRect( &rect, 10,10, 100, 100);
144  SetLastError( 0);
145  heightcheck = textheight = DrawTextExA(hdc, NULL, -1, &rect, DT_CALCRECT, NULL );
146  ok(EMPTY(rect), "rectangle should be empty got %s\n", wine_dbgstr_rect(&rect));
147  if (!textheight) /* Windows NT 4 */
148  {
149  if (conform_xp)
150  win_skip("XP conformity failed, skipping XP tests. Probably winNT\n");
151  conform_xp = FALSE;
152  }
153  else
154  ok(textheight!=0,"Failed to get textheight from DrawTextExA\n");
155 
156  SetRect( &rect, 10,10, 100, 100);
157  textheight = DrawTextA(hdc, NULL, -1, &rect, DT_CALCRECT);
158  ok(EMPTY(rect), "rectangle should be empty got %s\n", wine_dbgstr_rect(&rect));
159  if (conform_xp)
160  ok(textheight!=0,"Failed to get textheight from DrawTextA\n");
161  ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
162 
163  SetRect( &rect, 10,10, 100, 100);
164  heightcheck = textheight = DrawTextExA(hdc, NULL, 0, &rect, DT_CALCRECT, NULL );
165  ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
166  "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
167  if (conform_xp)
168  ok(textheight==0,"Got textheight from DrawTextExA\n");
169 
170  SetRect( &rect, 10,10, 100, 100);
171  textheight = DrawTextA(hdc, NULL, 0, &rect, DT_CALCRECT);
172  ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
173  "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
174  if (conform_xp)
175  ok(textheight==0,"Got textheight from DrawTextA\n");
176  ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
177 
178  /* DT_SINGLELINE tests */
179 
180  SetRect( &rect, 10,10, 100, 100);
181  heightcheck = textheight = DrawTextExA(hdc, text, 0, &rect, DT_CALCRECT|DT_SINGLELINE, NULL );
182  ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
183  "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
184  if (conform_xp)
185  ok(textheight==0,"Got textheight from DrawTextExA\n");
186 
187  SetRect( &rect, 10,10, 100, 100);
188  textheight = DrawTextA(hdc, text, 0, &rect, DT_CALCRECT|DT_SINGLELINE);
189  ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
190  "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
191  if (conform_xp)
192  ok(textheight==0,"Got textheight from DrawTextA\n");
193  ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
194 
195  SetRect( &rect, 10,10, 100, 100);
196  SetLastError( 0);
197  heightcheck = textheight = DrawTextExA(hdc, emptystring, -1, &rect, DT_CALCRECT|DT_SINGLELINE, NULL );
198  ok(!EMPTY(rect) && MODIFIED(rect), "rectangle should be modified got %s\n",
200  ok(textheight!=0,"Failed to get textheight from DrawTextExA\n");
201 
202  SetRect( &rect, 10,10, 100, 100);
203  textheight = DrawTextA(hdc, emptystring, -1, &rect, DT_CALCRECT|DT_SINGLELINE);
204  ok(!EMPTY(rect) && MODIFIED (rect), "rectangle should be modified got %s\n",
206  ok(textheight!=0,"Failed to get textheight from DrawTextA\n");
207  ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
208 
209  SetRect( &rect, 10,10, 100, 100);
210  SetLastError( 0);
211  heightcheck = textheight = DrawTextExA(hdc, NULL, -1, &rect, DT_CALCRECT|DT_SINGLELINE, NULL );
212  ok(!EMPTY(rect) && MODIFIED(rect), "rectangle should be modified got %s\n",
214  if (conform_xp)
215  ok(textheight!=0,"Failed to get textheight from DrawTextExA\n");
216 
217  SetRect( &rect, 10,10, 100, 100);
218  textheight = DrawTextA(hdc, NULL, -1, &rect, DT_CALCRECT|DT_SINGLELINE);
219  ok(!EMPTY(rect) && MODIFIED(rect), "rectangle should be modified got %s\n",
221  if (conform_xp)
222  ok(textheight!=0,"Failed to get textheight from DrawTextA\n");
223  ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
224 
225  SetRect( &rect, 10,10, 100, 100);
226  heightcheck = textheight = DrawTextExA(hdc, NULL, 0, &rect, DT_CALCRECT|DT_SINGLELINE, NULL );
227  ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
228  "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
229  if (conform_xp)
230  ok(textheight==0,"Got textheight from DrawTextExA\n");
231 
232  SetRect( &rect, 10,10, 100, 100);
233  textheight = DrawTextA(hdc, NULL, 0, &rect, DT_CALCRECT|DT_SINGLELINE);
234  ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
235  "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
236  if (conform_xp)
237  ok(textheight==0,"Got textheight from DrawTextA\n");
238  ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
239 
240  /* further tests with 0 count, NULL and empty strings */
241  heightcheck = textheight = DrawTextA(hdc, text, 0, &rect, 0);
242  if (conform_xp)
243  ok(textheight==0,"Got textheight from DrawTextA\n");
244  textheight = DrawTextExA(hdc, text, 0, &rect, 0, NULL );
245  if (conform_xp)
246  ok(textheight==0,"Got textheight from DrawTextExA\n");
247  ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
248  heightcheck = textheight = DrawTextA(hdc, emptystring, 0, &rect, 0);
249  if (conform_xp)
250  ok(textheight==0,"Got textheight from DrawTextA\n");
251  textheight = DrawTextExA(hdc, emptystring, 0, &rect, 0, NULL );
252  if (conform_xp)
253  ok(textheight==0,"Got textheight from DrawTextExA\n");
254  ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
255  heightcheck = textheight = DrawTextA(hdc, NULL, 0, &rect, 0);
256  if (conform_xp)
257  ok(textheight==0,"Got textheight from DrawTextA\n");
258  textheight = DrawTextExA(hdc, NULL, 0, &rect, 0, NULL );
259  if (conform_xp)
260  ok(textheight==0,"Got textheight from DrawTextExA\n");
261  ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
262  heightcheck = textheight = DrawTextA(hdc, emptystring, -1, &rect, 0);
263  ok(textheight!=0,"Failed to get textheight from DrawTextA\n");
264  textheight = DrawTextExA(hdc, emptystring, -1, &rect, 0, NULL );
265  ok(textheight!=0,"Failed to get textheight from DrawTextExA\n");
266  ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
267  heightcheck = textheight = DrawTextA(hdc, NULL, -1, &rect, 0);
268  if (conform_xp)
269  ok(textheight!=0,"Failed to get textheight from DrawTextA\n");
270  textheight = DrawTextExA(hdc, NULL, -1, &rect, 0, NULL );
271  if (conform_xp)
272  ok(textheight!=0,"Failed to get textheight from DrawTextExA\n");
273  ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
274  heightcheck = textheight = DrawTextA(hdc, NULL, 10, &rect, 0);
275  ok(textheight==0,"Got textheight from DrawTextA\n");
276  textheight = DrawTextExA(hdc, NULL, 10, &rect, 0, NULL );
277  ok(textheight==0,"Got textheight from DrawTextA\n");
278  ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
279 
280  /* When offset to top is zero, return 1 */
281  SetRectEmpty(&rect);
282  textheight = DrawTextExW(hdc, textW, -1, &rect, DT_SINGLELINE | DT_CALCRECT | DT_BOTTOM, NULL);
283  ok(textheight == 1, "Expect returned height:1 got:%d\n", textheight);
284 
285  SetRect(&rect, 0, 100, 0, 100);
286  textheight = DrawTextExW(hdc, textW, -1, &rect, DT_SINGLELINE | DT_CALCRECT | DT_BOTTOM, NULL);
287  ok(textheight == 1, "Expect returned height:1 got:%d\n", textheight);
288 
289  SetRectEmpty(&rect);
290  textheight = DrawTextExW(hdc, textW, -1, &rect, DT_SINGLELINE | DT_CALCRECT | DT_TOP, NULL);
291  /* Set top to text height and bottom zero, so bottom of drawn text to top is zero when DT_VCENTER is used */
292  SetRect(&rect, 0, textheight, 0, 0);
293  textheight = DrawTextExW(hdc, textW, -1, &rect, DT_SINGLELINE | DT_CALCRECT | DT_VCENTER, NULL);
294  ok(textheight == 1, "Expect returned height:1 got:%d\n", textheight);
295 
296  /* invalid dtp size test */
297  dtp.cbSize = -1; /* Invalid */
298  dtp.uiLengthDrawn = 1337;
299  textheight = DrawTextExA(hdc, text, 0, &rect, 0, &dtp);
300  ok(textheight==0,"Got textheight from DrawTextExA\n");
301  ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn);
302  dtp.uiLengthDrawn = 1337;
303  textheight = DrawTextExA(hdc, emptystring, 0, &rect, 0, &dtp);
304  ok(textheight==0,"Got textheight from DrawTextExA\n");
305  ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn);
306  dtp.uiLengthDrawn = 1337;
307  textheight = DrawTextExA(hdc, NULL, 0, &rect, 0, &dtp);
308  ok(textheight==0,"Got textheight from DrawTextExA\n");
309  ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn);
310  dtp.uiLengthDrawn = 1337;
311  textheight = DrawTextExA(hdc, emptystring, -1, &rect, 0, &dtp);
312  ok(textheight==0,"Got textheight from DrawTextExA\n");
313  ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn);
314  dtp.uiLengthDrawn = 1337;
315  textheight = DrawTextExA(hdc, NULL, -1, &rect, 0, &dtp);
316  ok(textheight==0,"Got textheight from DrawTextExA\n");
317  ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn);
318 
319  /* Margin calculations */
320  dtp.cbSize = sizeof(dtp);
321  dtp.iLeftMargin = 0;
322  dtp.iRightMargin = 0;
323  SetRectEmpty(&rect);
324  DrawTextExA(hdc, text, -1, &rect, DT_CALCRECT, &dtp);
325  textlen = rect.right; /* Width without margin */
326  dtp.iLeftMargin = 8;
327  SetRectEmpty(&rect);
328  DrawTextExA(hdc, text, -1, &rect, DT_CALCRECT, &dtp);
329  ok(rect.right==dtp.iLeftMargin+textlen ,"Incorrect left margin calculated rc(%d,%d)\n", rect.left, rect.right);
330  dtp.iLeftMargin = 0;
331  dtp.iRightMargin = 8;
332  SetRectEmpty(&rect);
333  DrawTextExA(hdc, text, -1, &rect, DT_CALCRECT, &dtp);
334  ok(rect.right==dtp.iRightMargin+textlen ,"Incorrect right margin calculated rc(%d,%d)\n", rect.left, rect.right);
335 
336  /* Wide char versions */
337  SetRect( &rect, 10,10, 100, 100);
338  SetLastError( 0);
339  heightcheck = textheight = DrawTextExW(hdc, textW, 0, &rect, DT_CALCRECT, NULL );
341  ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
342  "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
343  ok(textheight!=0,"Failed to get textheight from DrawTextExW\n");
344 
345  SetRect( &rect, 10,10, 100, 100);
346  textheight = DrawTextW(hdc, textW, 0, &rect, DT_CALCRECT);
347  ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
348  "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
349  ok(textheight!=0,"Failed to get textheight from DrawTextW\n");
350  ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
351 
352  SetRect( &rect, 10,10, 100, 100);
353  heightcheck = textheight = DrawTextExW(hdc, emptystringW, -1, &rect, DT_CALCRECT, NULL );
354  ok(EMPTY(rect), "rectangle should be empty got %s\n", wine_dbgstr_rect(&rect));
355  ok(textheight!=0,"Failed to get textheight from DrawTextExW\n");
356 
357  SetRect( &rect, 10,10, 100, 100);
358  textheight = DrawTextW(hdc, emptystringW, -1, &rect, DT_CALCRECT);
359  ok(EMPTY(rect), "rectangle should be empty got %s\n", wine_dbgstr_rect(&rect));
360  ok(textheight!=0,"Failed to get textheight from DrawTextW\n");
361  ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
362 
363  SetRect( &rect, 10,10, 100, 100);
364  heightcheck = textheight = DrawTextExW(hdc, NULL, 0, &rect, DT_CALCRECT, NULL );
365  ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
366  "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
367  if (textheight) /* windows 2000 */
368  {
369  if (conform_xp)
370  win_skip("XP conformity failed, skipping XP tests. Probably win 2000\n");
371  conform_xp = FALSE;
372  }
373  else
374  ok(textheight==0,"Got textheight from DrawTextExW\n");
375 
376  SetRect( &rect, 10,10, 100, 100);
377  textheight = DrawTextW(hdc, NULL, 0, &rect, DT_CALCRECT);
378  ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
379  "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
380  if (conform_xp)
381  ok(textheight==0,"Got textheight from DrawTextW\n");
382  ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
383 
384  if (conform_xp) {
385  /* Crashes on NT4 */
386  SetRect( &rect, 10,10, 100, 100);
387  heightcheck = textheight = DrawTextExW(hdc, NULL, -1, &rect, DT_CALCRECT, NULL );
388  ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
389  "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
390  ok(textheight==0,"Got textheight from DrawTextExW\n");
391 
392  SetRect( &rect, 10,10, 100, 100);
393  textheight = DrawTextW(hdc, NULL, -1, &rect, DT_CALCRECT);
394  ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
395  "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
396  ok(textheight==0,"Got textheight from DrawTextW\n");
397  ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
398  }
399 
400 
401  /* DT_SINGLELINE tests */
402 
403  heightcheck = textheight = DrawTextExW(hdc, textW, 0, &rect, DT_CALCRECT|DT_SINGLELINE, NULL );
404  ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
405  "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
406  ok(textheight!=0,"Failed to get textheight from DrawTextExW\n");
407 
408  SetRect( &rect, 10,10, 100, 100);
409  textheight = DrawTextW(hdc, textW, 0, &rect, DT_CALCRECT|DT_SINGLELINE);
410  ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
411  "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
412  ok(textheight!=0,"Failed to get textheight from DrawTextW\n");
413  ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
414 
415  SetRect( &rect, 10,10, 100, 100);
416  heightcheck = textheight = DrawTextExW(hdc, emptystringW, -1, &rect, DT_CALCRECT|DT_SINGLELINE, NULL );
417  ok(!EMPTY(rect) && MODIFIED(rect), "rectangle should be modified got %s\n",
419  ok(textheight!=0,"Failed to get textheight from DrawTextExW\n");
420 
421  SetRect( &rect, 10,10, 100, 100);
422  textheight = DrawTextW(hdc, emptystringW, -1, &rect, DT_CALCRECT|DT_SINGLELINE);
423  ok(!EMPTY(rect) && MODIFIED(rect), "rectangle should be modified got %s\n",
425  ok(textheight!=0,"Failed to get textheight from DrawTextW\n");
426  ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
427 
428  if (conform_xp) {
429  /* Crashes on NT4 */
430  SetRect( &rect, 10,10, 100, 100);
431  heightcheck = textheight = DrawTextExW(hdc, NULL, -1, &rect, DT_CALCRECT|DT_SINGLELINE, NULL );
432  ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
433  "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
434  ok(textheight==0,"Got textheight from DrawTextExW\n");
435 
436  SetRect( &rect, 10,10, 100, 100);
437  textheight = DrawTextW(hdc, NULL, -1, &rect, DT_CALCRECT|DT_SINGLELINE);
438  ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
439  "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
440  ok(textheight==0,"Got textheight from DrawTextW\n");
441  ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
442  }
443 
444  SetRect( &rect, 10,10, 100, 100);
445  heightcheck = textheight = DrawTextExW(hdc, NULL, 0, &rect, DT_CALCRECT|DT_SINGLELINE, NULL );
446  ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
447  "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
448  if (conform_xp)
449  ok(textheight==0,"Got textheight from DrawTextExW\n");
450 
451  SetRect( &rect, 10,10, 100, 100);
452  textheight = DrawTextW(hdc, NULL, 0, &rect, DT_CALCRECT|DT_SINGLELINE);
453  ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
454  "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
455  if (conform_xp)
456  ok(textheight==0,"Got textheight from DrawTextW\n");
457  ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
458 
459  /* further tests with NULL and empty strings */
460  heightcheck = textheight = DrawTextW(hdc, textW, 0, &rect, 0);
461  ok(textheight!=0,"Failed to get textheight from DrawTextW\n");
462  textheight = DrawTextExW(hdc, textW, 0, &rect, 0, NULL );
463  ok(textheight!=0,"Failed to get textheight from DrawTextExW\n");
464  ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
465  heightcheck = textheight = DrawTextW(hdc, emptystringW, 0, &rect, 0);
466  ok(textheight!=0,"Failed to get textheight from DrawTextW\n");
467  textheight = DrawTextExW(hdc, emptystringW, 0, &rect, 0, NULL );
468  ok(textheight!=0,"Failed to get textheight from DrawTextExW\n");
469  ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
470  heightcheck = textheight = DrawTextW(hdc, NULL, 0, &rect, 0);
471  if (conform_xp)
472  ok(textheight==0,"Got textheight from DrawTextW\n");
473  textheight = DrawTextExW(hdc, NULL, 0, &rect, 0, NULL );
474  if (conform_xp)
475  ok(textheight==0,"Got textheight from DrawTextExW\n");
476  ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
477  heightcheck = textheight = DrawTextW(hdc, emptystringW, -1, &rect, 0);
478  ok(textheight!=0,"Failed to get textheight from DrawTextW\n");
479  textheight = DrawTextExW(hdc, emptystringW, -1, &rect, 0, NULL );
480  ok(textheight!=0,"Failed to get textheight from DrawTextExW\n");
481  ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
482  if (conform_xp) {
483  /* Crashes on NT4 */
484  heightcheck = textheight = DrawTextW(hdc, NULL, -1, &rect, 0);
485  ok(textheight==0,"Got textheight from DrawTextW\n");
486  textheight = DrawTextExW(hdc, NULL, -1, &rect, 0, NULL );
487  ok(textheight==0,"Got textheight from DrawTextExW\n");
488  ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
489  heightcheck = textheight = DrawTextW(hdc, NULL, 10, &rect, 0);
490  ok(textheight==0,"Got textheight from DrawTextW\n");
491  textheight = DrawTextExW(hdc, NULL, 10, &rect, 0, NULL );
492  ok(textheight==0,"Got textheight from DrawTextW\n");
493  ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
494  }
495 
496  dtp.cbSize = -1; /* Invalid */
497  dtp.uiLengthDrawn = 1337;
498  textheight = DrawTextExW(hdc, textW, 0, &rect, 0, &dtp);
499  ok(textheight!=0,"Failed to get textheight from DrawTextExW\n");
500  ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn);
501  dtp.uiLengthDrawn = 1337;
502  textheight = DrawTextExW(hdc, emptystringW, 0, &rect, 0, &dtp);
503  if (conform_xp)
504  ok(textheight==0,"Got textheight from DrawTextExW\n");
505  ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn);
506  dtp.uiLengthDrawn = 1337;
507  textheight = DrawTextExW(hdc, NULL, 0, &rect, 0, &dtp);
508  if (conform_xp)
509  ok(textheight==0,"Got textheight from DrawTextExW\n");
510  ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn);
511  dtp.uiLengthDrawn = 1337;
512  textheight = DrawTextExW(hdc, emptystringW, -1, &rect, 0, &dtp);
513  ok(textheight==0,"Got textheight from DrawTextExW\n");
514  ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn);
515  if (conform_xp) {
516  /* Crashes on NT4 */
517  dtp.uiLengthDrawn = 1337;
518  textheight = DrawTextExW(hdc, NULL, -1, &rect, 0, &dtp);
519  ok(textheight==0,"Got textheight from DrawTextExW\n");
520  ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn);
521  }
522  }
523 
524  /* More test cases from bug 12226 */
525  SetRectEmpty(&rect);
526  textheight = DrawTextA(hdc, emptystring, -1, &rect, DT_CALCRECT | DT_LEFT | DT_SINGLELINE);
527  ok(textheight, "DrawTextA error %u\n", GetLastError());
528  ok(0 == rect.left, "expected 0, got %d\n", rect.left);
529  ok(0 == rect.right, "expected 0, got %d\n", rect.right);
530  ok(0 == rect.top, "expected 0, got %d\n", rect.top);
531  ok(rect.bottom, "rect.bottom should not be 0\n");
532 
533  SetRectEmpty(&rect);
534  textheight = DrawTextW(hdc, emptystringW, -1, &rect, DT_CALCRECT | DT_LEFT | DT_SINGLELINE);
535  if (!textheight && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
536  {
537  win_skip( "DrawTextW not implemented\n" );
538  }
539  else
540  {
541  ok(textheight, "DrawTextW error %u\n", GetLastError());
542  ok(0 == rect.left, "expected 0, got %d\n", rect.left);
543  ok(0 == rect.right, "expected 0, got %d\n", rect.right);
544  ok(0 == rect.top, "expected 0, got %d\n", rect.top);
545  ok(rect.bottom, "rect.bottom should not be 0\n");
546  }
547 
548  SetRect(&rect, 0, 0, 1, 1);
549  heightcheck = DrawTextA(hdc, wordbreak_text, -1, &rect, DT_CALCRECT);
550  SetRect(&rect, 0, 0, 1, 1);
551  textheight = DrawTextA(hdc, wordbreak_text, -1, &rect, DT_CALCRECT | DT_WORDBREAK);
552  ok(textheight == heightcheck * 2, "Got unexpected textheight %d, expected %d.\n",
553  textheight, heightcheck * 2);
554  SetRect(&rect, 0, 0, 1, 1);
555  textheight = DrawTextA(hdc, wordbreak_text, -1, &rect, DT_CALCRECT | DT_WORDBREAK | DT_EDITCONTROL);
556  ok(textheight >= heightcheck * 6, "Got unexpected textheight %d, expected at least %d.\n",
557  textheight, heightcheck * 6);
558 
559  SetRect(&rect, 0, 0, 1, 1);
560  heightcheck = DrawTextW(hdc, wordbreak_textW, -1, &rect, DT_CALCRECT);
561  SetRect(&rect, 0, 0, 1, 1);
562  textheight = DrawTextW(hdc, wordbreak_textW, -1, &rect, DT_CALCRECT | DT_WORDBREAK);
563  ok(textheight == heightcheck * 2, "Got unexpected textheight %d, expected %d.\n",
564  textheight, heightcheck * 2);
565  SetRect(&rect, 0, 0, 1, 1);
566  textheight = DrawTextW(hdc, wordbreak_textW, -1, &rect, DT_CALCRECT | DT_WORDBREAK | DT_EDITCONTROL);
567  ok(textheight >= heightcheck * 6, "Got unexpected textheight %d, expected at least %d.\n",
568  textheight, heightcheck * 6);
569 
570  /* DT_TABSTOP | DT_EXPANDTABS tests */
571  SetRect( &rect, 0,0, 10, 10);
572  textheight = DrawTextA(hdc, tabstring, -1, &rect, DT_TABSTOP | DT_EXPANDTABS );
573  ok(textheight >= heightcheck, "Got unexpected textheight %d\n", textheight);
574 
575  SetRect( &rect, 0,0, 10, 10);
576  memset(&dtp, 0, sizeof(dtp));
577  dtp.cbSize = sizeof(dtp);
578  textheight = DrawTextExA(hdc, tabstring, -1, &rect, DT_CALCRECT, &dtp);
579  ok(textheight >= heightcheck, "Got unexpected textheight %d\n", textheight);
580  ok(dtp.iTabLength == 0, "invalid dtp.iTabLength = %i\n",dtp.iTabLength);
581 
582  SetRect( &rect2, 0,0, 10, 10);
583  memset(&dtp, 0, sizeof(dtp));
584  dtp.cbSize = sizeof(dtp);
585  textheight = DrawTextExA(hdc, tabstring, -1, &rect2, DT_CALCRECT | DT_TABSTOP | DT_EXPANDTABS, &dtp);
586  ok(textheight >= heightcheck, "Got unexpected textheight %d\n", textheight);
587  ok(dtp.iTabLength == 0, "invalid dtp.iTabLength = %i\n",dtp.iTabLength);
588  ok(rect.left == rect2.left && rect.right != rect2.right && rect.top == rect2.top && rect.bottom == rect2.bottom,
589  "incorrect rect %s rect2 %s\n", wine_dbgstr_rect(&rect), wine_dbgstr_rect(&rect2));
590 
591  SetRect( &rect, 0,0, 10, 10);
592  memset(&dtp, 0, sizeof(dtp));
593  dtp.cbSize = sizeof(dtp);
594  dtp.iTabLength = 8;
595  textheight = DrawTextExA(hdc, tabstring, -1, &rect, DT_CALCRECT | DT_TABSTOP | DT_EXPANDTABS, &dtp);
596  ok(textheight >= heightcheck, "Got unexpected textheight %d\n", textheight);
597  ok(dtp.iTabLength == 8, "invalid dtp.iTabLength = %i\n",dtp.iTabLength);
598  ok(rect.left == rect2.left, "unexpected value %d, got %d\n", rect.left, rect2.left);
599  /* XP, 2003 appear to not give the same values. */
600  ok(rect.right == rect2.right || broken(rect.right > rect2.right), "unexpected value %d, got %d\n",rect.right, rect2.right);
601  ok(rect.top == rect2.top, "unexpected value %d, got %d\n", rect.top, rect2.top);
602  ok(rect.bottom == rect2.bottom , "unexpected value %d, got %d\n", rect.bottom, rect2.bottom);
603 
604 
605  SelectObject(hdc, hOldFont);
607  ok( ret, "DeleteObject error %u\n", GetLastError());
608 
609  /* Clean up */
610  ret = ReleaseDC(hwnd, hdc);
611  ok( ret, "ReleaseDC error %u\n", GetLastError());
613  ok( ret, "DestroyWindow error %u\n", GetLastError());
614 }
int WINAPI DrawTextExW(_In_ HDC hdc, _Inout_updates_opt_(cchText) LPWSTR lpchText, _In_ int cchText, _Inout_ LPRECT lprc, _In_ UINT format, _In_opt_ LPDRAWTEXTPARAMS lpdtp)
#define DT_EXPANDTABS
Definition: winuser.h:532
RECT rect2
Definition: edittest.c:51
const DOCKBAR PVOID HWND HWND * hwnd
Definition: tooldock.h:22
#define DT_TABSTOP
Definition: winuser.h:541
#define TRUE
Definition: types.h:120
#define DEFAULT_QUALITY
Definition: wingdi.h:435
HDC WINAPI GetDC(_In_opt_ HWND)
HFONT WINAPI CreateFontIndirectA(_In_ const LOGFONTA *)
#define EMPTY(rect)
Definition: text.c:32
const WCHAR * text
Definition: package.c:1827
int WINAPI DrawTextExA(_In_ HDC hdc, _Inout_updates_opt_(cchText) LPSTR lpchText, _In_ int cchText, _Inout_ LPRECT lprc, _In_ UINT format, _In_opt_ LPDRAWTEXTPARAMS lpdtp)
char CHAR
Definition: xmlstorage.h:175
#define DT_WORDBREAK
Definition: winuser.h:544
static HDC
Definition: imagelist.c:92
LONG top
Definition: windef.h:307
HGDIOBJ WINAPI SelectObject(_In_ HDC, _In_ HGDIOBJ)
Definition: dc.c:1497
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
BOOL WINAPI DeleteObject(_In_ HGDIOBJ)
BYTE lfCharSet
Definition: dimm.idl:50
LONG left
Definition: windef.h:306
LONG right
Definition: windef.h:308
#define DT_NOPREFIX
Definition: winuser.h:537
BOOL WINAPI DestroyWindow(_In_ HWND)
int32_t INT
Definition: typedefs.h:56
& rect
Definition: startmenu.cpp:1413
HFONT hFont
Definition: main.c:53
#define MODIFIED(rect)
Definition: text.c:31
#define DT_LEFT
Definition: winuser.h:534
#define DT_CALCRECT
Definition: winuser.h:526
unsigned int BOOL
Definition: ntddk_ex.h:94
int WINAPI SetMapMode(_In_ HDC, _In_ int)
LONG lfHeight
Definition: dimm.idl:42
#define CLIP_DEFAULT_PRECIS
Definition: wingdi.h:425
int WINAPI ReleaseDC(_In_opt_ HWND, _In_ HDC)
BOOL WINAPI IsRectEmpty(_In_ LPCRECT)
LONG lfWeight
Definition: dimm.idl:46
smooth NULL
Definition: ftsmooth.c:416
#define DT_VCENTER
Definition: winuser.h:543
#define trace
Definition: atltest.h:70
__wchar_t WCHAR
Definition: xmlstorage.h:180
const char * wine_dbgstr_rect(const RECT *rect)
#define SetLastError(x)
Definition: compat.h:417
int iRightMargin
Definition: winuser.h:3075
LPSTR WINAPI lstrcpyA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:100
static const WCHAR emptystringW[]
Definition: profile.c:96
int ret
HDC hdc
Definition: main.c:9
int WINAPI GetDeviceCaps(_In_opt_ HDC, _In_ int)
BOOL WINAPI SetRectEmpty(_Out_ LPRECT)
static const WCHAR textW[]
Definition: itemdlg.c:1559
#define broken(x)
Definition: _sntprintf.h:21
BYTE lfQuality
Definition: dimm.idl:53
#define DT_NOCLIP
Definition: winuser.h:536
#define DT_SINGLELINE
Definition: winuser.h:540
#define FW_DONTCARE
Definition: wingdi.h:367
INT WINAPI DrawTextA(HDC hdc, LPCSTR str, INT count, LPRECT rect, UINT flags)
Definition: font.c:373
BOOL WINAPI SetRect(_Out_ LPRECT, _In_ int, _In_ int, _In_ int, _In_ int)
int WINAPI lstrlenA(LPCSTR lpString)
Definition: lstring.c:145
BYTE lfClipPrecision
Definition: dimm.idl:52
#define DT_EXTERNALLEADING
Definition: winuser.h:533
#define ok(value,...)
Definition: atltest.h:57
#define DT_TOP
Definition: winuser.h:542
#define WS_POPUP
Definition: pedump.c:616
static DWORD *static HFONT(WINAPI *pCreateFontIndirectExA)(const ENUMLOGFONTEXDVA *)
#define MM_TEXT
Definition: wingdi.h:872
HWND WINAPI CreateWindowExA(_In_ DWORD dwExStyle, _In_opt_ LPCSTR lpClassName, _In_opt_ LPCSTR lpWindowName, _In_ DWORD dwStyle, _In_ int X, _In_ int Y, _In_ int nWidth, _In_ int nHeight, _In_opt_ HWND hWndParent, _In_opt_ HMENU hMenu, _In_opt_ HINSTANCE hInstance, _In_opt_ LPVOID lpParam)
CHAR lfFaceName[LF_FACESIZE]
Definition: dimm.idl:55
#define ERROR_CALL_NOT_IMPLEMENTED
Definition: compat.h:92
LONG bottom
Definition: windef.h:309
UINT uiLengthDrawn
Definition: winuser.h:3076
#define LOGPIXELSY
Definition: wingdi.h:718
#define ANSI_CHARSET
Definition: wingdi.h:382
#define memset(x, y, z)
Definition: compat.h:39
#define DT_BOTTOM
Definition: winuser.h:525
#define win_skip
Definition: test.h:150
#define MM_HIENGLISH
Definition: wingdi.h:867
#define MulDiv(x, y, z)
Definition: gdifloat.h:86
#define DT_EDITCONTROL
Definition: winuser.h:528
INT WINAPI DrawTextW(HDC hdc, LPCWSTR str, INT count, LPRECT rect, UINT flags)
Definition: defwnd.c:17

Referenced by START_TEST().

◆ test_TabbedText()

static void test_TabbedText ( void  )
static

Definition at line 639 of file text.c.

640 {
641  HWND hwnd;
642  HDC hdc;
643  BOOL ret;
644  TEXTMETRICA tm;
645  DWORD extent;
646  INT tabs[8], cx, cy, tab, tabcount,t,align;
647 
648  /* Initialization */
649  hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP,
650  0, 0, 200, 200, 0, 0, 0, NULL);
651  ok(hwnd != 0, "CreateWindowExA error %u\n", GetLastError());
652  hdc = GetDC(hwnd);
653  ok(hdc != 0, "GetDC error %u\n", GetLastError());
654 
655  ret = GetTextMetricsA( hdc, &tm);
656  ok( ret, "GetTextMetrics error %u\n", GetLastError());
657 
658  extent = GetTabbedTextExtentA( hdc, "x", 0, 1, tabs);
659  ok( extent == 0, "GetTabbedTextExtentA returned non-zero on nCount == 0\n");
660 
661  extent = GetTabbedTextExtentA( hdc, "x", 1, 1, tabs);
662  cx = LOWORD( extent);
663  cy = HIWORD( extent);
664  trace( "cx is %d cy is %d\n", cx, cy);
665 
666  align=1;
667  for( t=-1; t<=1; t++) { /* slightly adjust the 4 char tabstop, to
668  catch the one off errors */
669  tab = (cx *4 + t);
670  /* test the special case tabcount =1 and the general array (80 of tabs */
671  for( tabcount = 1; tabcount <= 8; tabcount +=7) {
672  TABTEST( align * tab, tabcount, "\t", MAKELONG(tab, cy))
673  TABTEST( align * tab, tabcount, "xxx\t", MAKELONG(tab, cy))
674  TABTEST( align * tab, tabcount, "\tx", MAKELONG(tab+cx, cy))
675  TABTEST( align * tab, tabcount, "\t\t", MAKELONG(tab*2, cy))
676  TABTEST( align * tab, tabcount, "\tx\t", MAKELONG(tab*2, cy))
677  TABTEST( align * tab, tabcount, "x\tx", MAKELONG(tab+cx, cy))
678  TABTEST( align * tab, tabcount, "xx\tx", MAKELONG(tab+cx, cy))
679  TABTEST( align * tab, tabcount, "xxx\tx", MAKELONG(tab+cx, cy))
680  TABTEST( align * tab, tabcount, "xxxx\tx", MAKELONG(t>0 ? tab + cx : 2*tab+cx, cy))
681  TABTEST( align * tab, tabcount, "xxxxx\tx", MAKELONG(2*tab+cx, cy))
682  }
683  }
684  align=-1;
685  for( t=-1; t<=1; t++) { /* slightly adjust the 4 char tabstop, to
686  catch the one off errors */
687  tab = (cx *4 + t);
688  /* test the special case tabcount =1 and the general array (8) of tabs */
689  for( tabcount = 1; tabcount <= 8; tabcount +=7) {
690  TABTEST( align * tab, tabcount, "\t", MAKELONG(tab, cy))
691  TABTEST( align * tab, tabcount, "xxx\t", MAKELONG(tab, cy))
692  TABTEST( align * tab, tabcount, "\tx", MAKELONG(tab, cy))
693  TABTEST( align * tab, tabcount, "\t\t", MAKELONG(tab*2, cy))
694  TABTEST( align * tab, tabcount, "\tx\t", MAKELONG(tab*2, cy))
695  TABTEST( align * tab, tabcount, "x\tx", MAKELONG(tab, cy))
696  TABTEST( align * tab, tabcount, "xx\tx", MAKELONG(tab, cy))
697  TABTEST( align * tab, tabcount, "xxx\tx", MAKELONG(4 * cx >= tab ? 2*tab :tab, cy))
698  TABTEST( align * tab, tabcount, "xxxx\tx", MAKELONG(2*tab, cy))
699  TABTEST( align * tab, tabcount, "xxxxx\tx", MAKELONG(2*tab, cy))
700  }
701  }
702 
703  ReleaseDC( hwnd, hdc );
704  DestroyWindow( hwnd );
705 }
const DOCKBAR PVOID HWND HWND * hwnd
Definition: tooldock.h:22
HDC WINAPI GetDC(_In_opt_ HWND)
static HDC
Definition: imagelist.c:92
DWORD WINAPI GetTabbedTextExtentA(_In_ HDC hdc, _In_reads_(chCount) LPCSTR lpString, _In_ int chCount, _In_ int nTabPositions, _In_reads_opt_(nTabPositions) CONST INT *lpnTabStopPositions)
GLdouble GLdouble t
Definition: gl.h:2047
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
int align(int length, int align)
Definition: dsound8.c:36
BOOL WINAPI DestroyWindow(_In_ HWND)
int32_t INT
Definition: typedefs.h:56
unsigned int BOOL
Definition: ntddk_ex.h:94
int WINAPI ReleaseDC(_In_opt_ HWND, _In_ HDC)
_Out_opt_ int _Out_opt_ int * cy
Definition: commctrl.h:581
#define MAKELONG(a, b)
Definition: typedefs.h:248
smooth NULL
Definition: ftsmooth.c:416
#define trace
Definition: atltest.h:70
unsigned long DWORD
Definition: ntddk_ex.h:95
int ret
HDC hdc
Definition: main.c:9
Definition: time.h:76
#define ok(value,...)
Definition: atltest.h:57
#define WS_POPUP
Definition: pedump.c:616
_Out_opt_ int * cx
Definition: commctrl.h:581
HWND WINAPI CreateWindowExA(_In_ DWORD dwExStyle, _In_opt_ LPCSTR lpClassName, _In_opt_ LPCSTR lpWindowName, _In_ DWORD dwStyle, _In_ int X, _In_ int Y, _In_ int nWidth, _In_ int nHeight, _In_opt_ HWND hWndParent, _In_opt_ HMENU hMenu, _In_opt_ HINSTANCE hInstance, _In_opt_ LPVOID lpParam)
#define HIWORD(l)
Definition: typedefs.h:246
BOOL WINAPI GetTextMetricsA(_In_ HDC hdc, _Out_ LPTEXTMETRICA lptm)
Definition: text.c:200
#define LOWORD(l)
Definition: pedump.c:82
#define TABTEST(tabval, tabcount, string, _exp)
Definition: text.c:628

Referenced by START_TEST().