ReactOS  0.4.14-dev-55-g2da92ac
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 613 of file text.c.

Function Documentation

◆ START_TEST()

START_TEST ( text  )

Definition at line 824 of file text.c.

825 {
826  test_TabbedText();
828  test_DrawState();
830 }
static void test_DrawTextCalcRect(void)
Definition: text.c:34
static void test_DrawState(void)
Definition: text.c:692
static void test_TabbedText(void)
Definition: text.c:624
static void test_CharToOem_OemToChar(void)
Definition: text.c:732

◆ strfmt()

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

Definition at line 602 of file text.c.

603 {
604  unsigned int i,j ;
605  for(i=0,j=0;i<=strlen(str);i++,j++)
606  if((strout[j]=str[i])=='\t') {
607  strout[j++]='\\';
608  strout[j]='t';
609  }
610 }
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 732 of file text.c.

733 {
734  static const WCHAR helloWorldW[] = {'H','e','l','l','o',' ','W','o','r','l','d',0};
735  static const WCHAR emptyW[] = {0};
736  static const char helloWorld[] = "Hello World";
737  static const struct
738  {
739  BOOL src, dst, ret;
740  }
741  tests[] =
742  {
743  { FALSE, FALSE, FALSE },
744  { TRUE, FALSE, FALSE },
745  { FALSE, TRUE, FALSE },
746  { TRUE, TRUE, TRUE },
747  };
748  BOOL ret;
749  int i;
750  char oem;
751  WCHAR uni, expect;
752 
753  for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
754  {
755  const char *expected = tests[i].ret ? helloWorld : "";
756  const char *src = tests[i].src ? helloWorld : NULL;
757  char buf[64], *dst = tests[i].dst ? buf : NULL;
758 
759  memset(buf, 0, sizeof(buf));
760  ret = CharToOemA(src, dst);
761  ok(ret == tests[i].ret, "test %d: expected %d, got %d\n", i, tests[i].ret, ret);
762  ok(!strcmp(buf, expected), "test %d: got '%s'\n", i, buf);
763 
764  memset(buf, 0, sizeof(buf));
765  ret = CharToOemBuffA(src, dst, sizeof(helloWorld));
766  ok(ret == tests[i].ret, "test %d: expected %d, got %d\n", i, tests[i].ret, ret);
767  ok(!strcmp(buf, expected), "test %d: got '%s'\n", i, buf);
768 
769  memset(buf, 0, sizeof(buf));
770  ret = OemToCharA(src, dst);
771  ok(ret == tests[i].ret, "test %d: expected %d, got %d\n", i, tests[i].ret, ret);
772  ok(!strcmp(buf, expected), "test %d: got '%s'\n", i, buf);
773 
774  memset(buf, 0, sizeof(buf));
775  ret = OemToCharBuffA(src, dst, sizeof(helloWorld));
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 
780  for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
781  {
782  const char *expected = tests[i].ret ? helloWorld : "";
783  const WCHAR *src = tests[i].src ? helloWorldW : NULL;
784  char buf[64], *dst = tests[i].dst ? buf : NULL;
785 
786  memset(buf, 0, sizeof(buf));
787  ret = CharToOemW(src, dst);
788  ok(ret == tests[i].ret, "test %d: expected %d, got %d\n", i, tests[i].ret, ret);
789  ok(!strcmp(buf, expected), "test %d: got '%s'\n", i, buf);
790 
791  memset(buf, 0, sizeof(buf));
792  ret = CharToOemBuffW(src, dst, sizeof(helloWorldW)/sizeof(WCHAR));
793  ok(ret == tests[i].ret, "test %d: expected %d, got %d\n", i, tests[i].ret, ret);
794  ok(!strcmp(buf, expected), "test %d: got '%s'\n", i, buf);
795  }
796 
797  for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
798  {
799  const WCHAR *expected = tests[i].ret ? helloWorldW : emptyW;
800  const char *src = tests[i].src ? helloWorld : NULL;
801  WCHAR buf[64], *dst = tests[i].dst ? buf : NULL;
802 
803  memset(buf, 0, sizeof(buf));
804  ret = OemToCharW(src, dst);
805  ok(ret == tests[i].ret, "test %d: expected %d, got %d\n", i, tests[i].ret, ret);
806  ok(!lstrcmpW(buf, expected), "test %d: got '%s'\n", i, wine_dbgstr_w(buf));
807 
808  memset(buf, 0, sizeof(buf));
809  ret = OemToCharBuffW(src, dst, sizeof(helloWorld));
810  ok(ret == tests[i].ret, "test %d: expected %d, got %d\n", i, tests[i].ret, ret);
811  ok(!lstrcmpW(buf, expected), "test %d: got '%s'\n", i, wine_dbgstr_w(buf));
812  }
813 
814  for (i = 0; i < 0x100; i++)
815  {
816  oem = i;
817  ret = OemToCharBuffW( &oem, &uni, 1 );
818  ok( ret, "%02x: returns FALSE\n", i );
820  ok( uni == expect, "%02x: got %04x expected %04x\n", i, uni, expect );
821  }
822 }
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:36
#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 692 of file text.c.

693 {
694  static const char text[] = "Sample text string";
695  HWND hwnd;
696  HDC hdc;
697  BOOL ret;
698 
699  hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP,
700  0, 0, 200, 200, 0, 0, 0, NULL);
701  assert(hwnd);
702 
703  hdc = GetDC(hwnd);
704  assert(hdc);
705 
706  SetLastError(0xdeadbeef);
708  0, 0, 10, 10, DST_TEXT);
709  ok(ret, "DrawState error %u\n", GetLastError());
710 
711  SetLastError(0xdeadbeef);
713  0, 0, 10, 10, DST_TEXT);
714  ok(ret, "DrawState error %u\n", GetLastError());
715 
716  SetLastError(0xdeadbeef);
718  0, 0, 10, 10, DST_TEXT);
719  ok(!ret || broken(ret) /* win98 */, "DrawState succeeded\n");
720  ok(GetLastError() == 0xdeadbeef, "not expected error %u\n", GetLastError());
721 
722  SetLastError(0xdeadbeef);
724  0, 0, 10, 10, DST_TEXT);
725  ok(!ret || broken(ret) /* win98 */, "DrawState succeeded\n");
726  ok(GetLastError() == 0xdeadbeef, "not expected error %u\n", GetLastError());
727 
728  ReleaseDC(hwnd, hdc);
730 }
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:409
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 
281  /* invalid dtp size test */
282  dtp.cbSize = -1; /* Invalid */
283  dtp.uiLengthDrawn = 1337;
284  textheight = DrawTextExA(hdc, text, 0, &rect, 0, &dtp);
285  ok(textheight==0,"Got textheight from DrawTextExA\n");
286  ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn);
287  dtp.uiLengthDrawn = 1337;
288  textheight = DrawTextExA(hdc, emptystring, 0, &rect, 0, &dtp);
289  ok(textheight==0,"Got textheight from DrawTextExA\n");
290  ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn);
291  dtp.uiLengthDrawn = 1337;
292  textheight = DrawTextExA(hdc, NULL, 0, &rect, 0, &dtp);
293  ok(textheight==0,"Got textheight from DrawTextExA\n");
294  ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn);
295  dtp.uiLengthDrawn = 1337;
296  textheight = DrawTextExA(hdc, emptystring, -1, &rect, 0, &dtp);
297  ok(textheight==0,"Got textheight from DrawTextExA\n");
298  ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn);
299  dtp.uiLengthDrawn = 1337;
300  textheight = DrawTextExA(hdc, NULL, -1, &rect, 0, &dtp);
301  ok(textheight==0,"Got textheight from DrawTextExA\n");
302  ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn);
303 
304  /* Margin calculations */
305  dtp.cbSize = sizeof(dtp);
306  dtp.iLeftMargin = 0;
307  dtp.iRightMargin = 0;
308  SetRectEmpty(&rect);
309  DrawTextExA(hdc, text, -1, &rect, DT_CALCRECT, &dtp);
310  textlen = rect.right; /* Width without margin */
311  dtp.iLeftMargin = 8;
312  SetRectEmpty(&rect);
313  DrawTextExA(hdc, text, -1, &rect, DT_CALCRECT, &dtp);
314  ok(rect.right==dtp.iLeftMargin+textlen ,"Incorrect left margin calculated rc(%d,%d)\n", rect.left, rect.right);
315  dtp.iLeftMargin = 0;
316  dtp.iRightMargin = 8;
317  SetRectEmpty(&rect);
318  DrawTextExA(hdc, text, -1, &rect, DT_CALCRECT, &dtp);
319  ok(rect.right==dtp.iRightMargin+textlen ,"Incorrect right margin calculated rc(%d,%d)\n", rect.left, rect.right);
320 
321  /* Wide char versions */
322  SetRect( &rect, 10,10, 100, 100);
323  SetLastError( 0);
324  heightcheck = textheight = DrawTextExW(hdc, textW, 0, &rect, DT_CALCRECT, NULL );
326  ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
327  "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
328  ok(textheight!=0,"Failed to get textheight from DrawTextExW\n");
329 
330  SetRect( &rect, 10,10, 100, 100);
331  textheight = DrawTextW(hdc, textW, 0, &rect, DT_CALCRECT);
332  ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
333  "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
334  ok(textheight!=0,"Failed to get textheight from DrawTextW\n");
335  ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
336 
337  SetRect( &rect, 10,10, 100, 100);
338  heightcheck = textheight = DrawTextExW(hdc, emptystringW, -1, &rect, DT_CALCRECT, NULL );
339  ok(EMPTY(rect), "rectangle should be empty got %s\n", wine_dbgstr_rect(&rect));
340  ok(textheight!=0,"Failed to get textheight from DrawTextExW\n");
341 
342  SetRect( &rect, 10,10, 100, 100);
343  textheight = DrawTextW(hdc, emptystringW, -1, &rect, DT_CALCRECT);
344  ok(EMPTY(rect), "rectangle should be empty got %s\n", wine_dbgstr_rect(&rect));
345  ok(textheight!=0,"Failed to get textheight from DrawTextW\n");
346  ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
347 
348  SetRect( &rect, 10,10, 100, 100);
349  heightcheck = textheight = DrawTextExW(hdc, NULL, 0, &rect, DT_CALCRECT, NULL );
350  ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
351  "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
352  if (textheight) /* windows 2000 */
353  {
354  if (conform_xp)
355  win_skip("XP conformity failed, skipping XP tests. Probably win 2000\n");
356  conform_xp = FALSE;
357  }
358  else
359  ok(textheight==0,"Got textheight from DrawTextExW\n");
360 
361  SetRect( &rect, 10,10, 100, 100);
362  textheight = DrawTextW(hdc, NULL, 0, &rect, DT_CALCRECT);
363  ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
364  "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
365  if (conform_xp)
366  ok(textheight==0,"Got textheight from DrawTextW\n");
367  ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
368 
369  if (conform_xp) {
370  /* Crashes on NT4 */
371  SetRect( &rect, 10,10, 100, 100);
372  heightcheck = textheight = DrawTextExW(hdc, NULL, -1, &rect, DT_CALCRECT, NULL );
373  ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
374  "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
375  ok(textheight==0,"Got textheight from DrawTextExW\n");
376 
377  SetRect( &rect, 10,10, 100, 100);
378  textheight = DrawTextW(hdc, NULL, -1, &rect, DT_CALCRECT);
379  ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
380  "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
381  ok(textheight==0,"Got textheight from DrawTextW\n");
382  ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
383  }
384 
385 
386  /* DT_SINGLELINE tests */
387 
388  heightcheck = textheight = DrawTextExW(hdc, textW, 0, &rect, DT_CALCRECT|DT_SINGLELINE, NULL );
389  ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
390  "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
391  ok(textheight!=0,"Failed to get textheight from DrawTextExW\n");
392 
393  SetRect( &rect, 10,10, 100, 100);
394  textheight = DrawTextW(hdc, textW, 0, &rect, DT_CALCRECT|DT_SINGLELINE);
395  ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
396  "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
397  ok(textheight!=0,"Failed to get textheight from DrawTextW\n");
398  ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
399 
400  SetRect( &rect, 10,10, 100, 100);
401  heightcheck = textheight = DrawTextExW(hdc, emptystringW, -1, &rect, DT_CALCRECT|DT_SINGLELINE, NULL );
402  ok(!EMPTY(rect) && MODIFIED(rect), "rectangle should be modified got %s\n",
404  ok(textheight!=0,"Failed to get textheight from DrawTextExW\n");
405 
406  SetRect( &rect, 10,10, 100, 100);
407  textheight = DrawTextW(hdc, emptystringW, -1, &rect, DT_CALCRECT|DT_SINGLELINE);
408  ok(!EMPTY(rect) && MODIFIED(rect), "rectangle should be modified got %s\n",
410  ok(textheight!=0,"Failed to get textheight from DrawTextW\n");
411  ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
412 
413  if (conform_xp) {
414  /* Crashes on NT4 */
415  SetRect( &rect, 10,10, 100, 100);
416  heightcheck = textheight = DrawTextExW(hdc, NULL, -1, &rect, DT_CALCRECT|DT_SINGLELINE, NULL );
417  ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
418  "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
419  ok(textheight==0,"Got textheight from DrawTextExW\n");
420 
421  SetRect( &rect, 10,10, 100, 100);
422  textheight = DrawTextW(hdc, NULL, -1, &rect, DT_CALCRECT|DT_SINGLELINE);
423  ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
424  "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
425  ok(textheight==0,"Got textheight from DrawTextW\n");
426  ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
427  }
428 
429  SetRect( &rect, 10,10, 100, 100);
430  heightcheck = textheight = DrawTextExW(hdc, NULL, 0, &rect, DT_CALCRECT|DT_SINGLELINE, NULL );
431  ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
432  "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
433  if (conform_xp)
434  ok(textheight==0,"Got textheight from DrawTextExW\n");
435 
436  SetRect( &rect, 10,10, 100, 100);
437  textheight = DrawTextW(hdc, NULL, 0, &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  if (conform_xp)
441  ok(textheight==0,"Got textheight from DrawTextW\n");
442  ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
443 
444  /* further tests with NULL and empty strings */
445  heightcheck = textheight = DrawTextW(hdc, textW, 0, &rect, 0);
446  ok(textheight!=0,"Failed to get textheight from DrawTextW\n");
447  textheight = DrawTextExW(hdc, textW, 0, &rect, 0, NULL );
448  ok(textheight!=0,"Failed to get textheight from DrawTextExW\n");
449  ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
450  heightcheck = textheight = DrawTextW(hdc, emptystringW, 0, &rect, 0);
451  ok(textheight!=0,"Failed to get textheight from DrawTextW\n");
452  textheight = DrawTextExW(hdc, emptystringW, 0, &rect, 0, NULL );
453  ok(textheight!=0,"Failed to get textheight from DrawTextExW\n");
454  ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
455  heightcheck = textheight = DrawTextW(hdc, NULL, 0, &rect, 0);
456  if (conform_xp)
457  ok(textheight==0,"Got textheight from DrawTextW\n");
458  textheight = DrawTextExW(hdc, NULL, 0, &rect, 0, NULL );
459  if (conform_xp)
460  ok(textheight==0,"Got textheight from DrawTextExW\n");
461  ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
462  heightcheck = textheight = DrawTextW(hdc, emptystringW, -1, &rect, 0);
463  ok(textheight!=0,"Failed to get textheight from DrawTextW\n");
464  textheight = DrawTextExW(hdc, emptystringW, -1, &rect, 0, NULL );
465  ok(textheight!=0,"Failed to get textheight from DrawTextExW\n");
466  ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
467  if (conform_xp) {
468  /* Crashes on NT4 */
469  heightcheck = textheight = DrawTextW(hdc, NULL, -1, &rect, 0);
470  ok(textheight==0,"Got textheight from DrawTextW\n");
471  textheight = DrawTextExW(hdc, NULL, -1, &rect, 0, NULL );
472  ok(textheight==0,"Got textheight from DrawTextExW\n");
473  ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
474  heightcheck = textheight = DrawTextW(hdc, NULL, 10, &rect, 0);
475  ok(textheight==0,"Got textheight from DrawTextW\n");
476  textheight = DrawTextExW(hdc, NULL, 10, &rect, 0, NULL );
477  ok(textheight==0,"Got textheight from DrawTextW\n");
478  ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
479  }
480 
481  dtp.cbSize = -1; /* Invalid */
482  dtp.uiLengthDrawn = 1337;
483  textheight = DrawTextExW(hdc, textW, 0, &rect, 0, &dtp);
484  ok(textheight!=0,"Failed to get textheight from DrawTextExW\n");
485  ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn);
486  dtp.uiLengthDrawn = 1337;
487  textheight = DrawTextExW(hdc, emptystringW, 0, &rect, 0, &dtp);
488  if (conform_xp)
489  ok(textheight==0,"Got textheight from DrawTextExW\n");
490  ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn);
491  dtp.uiLengthDrawn = 1337;
492  textheight = DrawTextExW(hdc, NULL, 0, &rect, 0, &dtp);
493  if (conform_xp)
494  ok(textheight==0,"Got textheight from DrawTextExW\n");
495  ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn);
496  dtp.uiLengthDrawn = 1337;
497  textheight = DrawTextExW(hdc, emptystringW, -1, &rect, 0, &dtp);
498  ok(textheight==0,"Got textheight from DrawTextExW\n");
499  ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn);
500  if (conform_xp) {
501  /* Crashes on NT4 */
502  dtp.uiLengthDrawn = 1337;
503  textheight = DrawTextExW(hdc, NULL, -1, &rect, 0, &dtp);
504  ok(textheight==0,"Got textheight from DrawTextExW\n");
505  ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn);
506  }
507  }
508 
509  /* More test cases from bug 12226 */
510  SetRectEmpty(&rect);
511  textheight = DrawTextA(hdc, emptystring, -1, &rect, DT_CALCRECT | DT_LEFT | DT_SINGLELINE);
512  ok(textheight, "DrawTextA error %u\n", GetLastError());
513  ok(0 == rect.left, "expected 0, got %d\n", rect.left);
514  ok(0 == rect.right, "expected 0, got %d\n", rect.right);
515  ok(0 == rect.top, "expected 0, got %d\n", rect.top);
516  ok(rect.bottom, "rect.bottom should not be 0\n");
517 
518  SetRectEmpty(&rect);
519  textheight = DrawTextW(hdc, emptystringW, -1, &rect, DT_CALCRECT | DT_LEFT | DT_SINGLELINE);
520  if (!textheight && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
521  {
522  win_skip( "DrawTextW not implemented\n" );
523  }
524  else
525  {
526  ok(textheight, "DrawTextW error %u\n", GetLastError());
527  ok(0 == rect.left, "expected 0, got %d\n", rect.left);
528  ok(0 == rect.right, "expected 0, got %d\n", rect.right);
529  ok(0 == rect.top, "expected 0, got %d\n", rect.top);
530  ok(rect.bottom, "rect.bottom should not be 0\n");
531  }
532 
533  SetRect(&rect, 0, 0, 1, 1);
534  heightcheck = DrawTextA(hdc, wordbreak_text, -1, &rect, DT_CALCRECT);
535  SetRect(&rect, 0, 0, 1, 1);
536  textheight = DrawTextA(hdc, wordbreak_text, -1, &rect, DT_CALCRECT | DT_WORDBREAK);
537  ok(textheight == heightcheck * 2, "Got unexpected textheight %d, expected %d.\n",
538  textheight, heightcheck * 2);
539  SetRect(&rect, 0, 0, 1, 1);
540  textheight = DrawTextA(hdc, wordbreak_text, -1, &rect, DT_CALCRECT | DT_WORDBREAK | DT_EDITCONTROL);
541  ok(textheight >= heightcheck * 6, "Got unexpected textheight %d, expected at least %d.\n",
542  textheight, heightcheck * 6);
543 
544  SetRect(&rect, 0, 0, 1, 1);
545  heightcheck = DrawTextW(hdc, wordbreak_textW, -1, &rect, DT_CALCRECT);
546  SetRect(&rect, 0, 0, 1, 1);
547  textheight = DrawTextW(hdc, wordbreak_textW, -1, &rect, DT_CALCRECT | DT_WORDBREAK);
548  ok(textheight == heightcheck * 2, "Got unexpected textheight %d, expected %d.\n",
549  textheight, heightcheck * 2);
550  SetRect(&rect, 0, 0, 1, 1);
551  textheight = DrawTextW(hdc, wordbreak_textW, -1, &rect, DT_CALCRECT | DT_WORDBREAK | DT_EDITCONTROL);
552  ok(textheight >= heightcheck * 6, "Got unexpected textheight %d, expected at least %d.\n",
553  textheight, heightcheck * 6);
554 
555  /* DT_TABSTOP | DT_EXPANDTABS tests */
556  SetRect( &rect, 0,0, 10, 10);
557  textheight = DrawTextA(hdc, tabstring, -1, &rect, DT_TABSTOP | DT_EXPANDTABS );
558  ok(textheight >= heightcheck, "Got unexpected textheight %d\n", textheight);
559 
560  SetRect( &rect, 0,0, 10, 10);
561  memset(&dtp, 0, sizeof(dtp));
562  dtp.cbSize = sizeof(dtp);
563  textheight = DrawTextExA(hdc, tabstring, -1, &rect, DT_CALCRECT, &dtp);
564  ok(textheight >= heightcheck, "Got unexpected textheight %d\n", textheight);
565  ok(dtp.iTabLength == 0, "invalid dtp.iTabLength = %i\n",dtp.iTabLength);
566 
567  SetRect( &rect2, 0,0, 10, 10);
568  memset(&dtp, 0, sizeof(dtp));
569  dtp.cbSize = sizeof(dtp);
570  textheight = DrawTextExA(hdc, tabstring, -1, &rect2, DT_CALCRECT | DT_TABSTOP | DT_EXPANDTABS, &dtp);
571  ok(textheight >= heightcheck, "Got unexpected textheight %d\n", textheight);
572  ok(dtp.iTabLength == 0, "invalid dtp.iTabLength = %i\n",dtp.iTabLength);
573  ok(rect.left == rect2.left && rect.right != rect2.right && rect.top == rect2.top && rect.bottom == rect2.bottom,
574  "incorrect rect %s rect2 %s\n", wine_dbgstr_rect(&rect), wine_dbgstr_rect(&rect2));
575 
576  SetRect( &rect, 0,0, 10, 10);
577  memset(&dtp, 0, sizeof(dtp));
578  dtp.cbSize = sizeof(dtp);
579  dtp.iTabLength = 8;
580  textheight = DrawTextExA(hdc, tabstring, -1, &rect, DT_CALCRECT | DT_TABSTOP | DT_EXPANDTABS, &dtp);
581  ok(textheight >= heightcheck, "Got unexpected textheight %d\n", textheight);
582  ok(dtp.iTabLength == 8, "invalid dtp.iTabLength = %i\n",dtp.iTabLength);
583  ok(rect.left == rect2.left, "unexpected value %d, got %d\n", rect.left, rect2.left);
584  /* XP, 2003 appear to not give the same values. */
585  ok(rect.right == rect2.right || broken(rect.right > rect2.right), "unexpected value %d, got %d\n",rect.right, rect2.right);
586  ok(rect.top == rect2.top, "unexpected value %d, got %d\n", rect.top, rect2.top);
587  ok(rect.bottom == rect2.bottom , "unexpected value %d, got %d\n", rect.bottom, rect2.bottom);
588 
589 
590  SelectObject(hdc, hOldFont);
592  ok( ret, "DeleteObject error %u\n", GetLastError());
593 
594  /* Clean up */
595  ret = ReleaseDC(hwnd, hdc);
596  ok( ret, "ReleaseDC error %u\n", GetLastError());
598  ok( ret, "DestroyWindow error %u\n", GetLastError());
599 }
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:292
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:291
LONG right
Definition: windef.h:293
#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 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:409
int iRightMargin
Definition: winuser.h:3074
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 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:294
UINT uiLengthDrawn
Definition: winuser.h:3075
#define LOGPIXELSY
Definition: wingdi.h:718
#define ANSI_CHARSET
Definition: wingdi.h:382
#define memset(x, y, z)
Definition: compat.h:39
#define win_skip
Definition: test.h:141
#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 624 of file text.c.

625 {
626  HWND hwnd;
627  HDC hdc;
628  BOOL ret;
629  TEXTMETRICA tm;
630  DWORD extent;
631  INT tabs[8], cx, cy, tab, tabcount,t,align;
632 
633  /* Initialization */
634  hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP,
635  0, 0, 200, 200, 0, 0, 0, NULL);
636  ok(hwnd != 0, "CreateWindowExA error %u\n", GetLastError());
637  hdc = GetDC(hwnd);
638  ok(hdc != 0, "GetDC error %u\n", GetLastError());
639 
640  ret = GetTextMetricsA( hdc, &tm);
641  ok( ret, "GetTextMetrics error %u\n", GetLastError());
642 
643  extent = GetTabbedTextExtentA( hdc, "x", 0, 1, tabs);
644  ok( extent == 0, "GetTabbedTextExtentA returned non-zero on nCount == 0\n");
645 
646  extent = GetTabbedTextExtentA( hdc, "x", 1, 1, tabs);
647  cx = LOWORD( extent);
648  cy = HIWORD( extent);
649  trace( "cx is %d cy is %d\n", cx, cy);
650 
651  align=1;
652  for( t=-1; t<=1; t++) { /* slightly adjust the 4 char tabstop, to
653  catch the one off errors */
654  tab = (cx *4 + t);
655  /* test the special case tabcount =1 and the general array (80 of tabs */
656  for( tabcount = 1; tabcount <= 8; tabcount +=7) {
657  TABTEST( align * tab, tabcount, "\t", MAKELONG(tab, cy))
658  TABTEST( align * tab, tabcount, "xxx\t", MAKELONG(tab, cy))
659  TABTEST( align * tab, tabcount, "\tx", MAKELONG(tab+cx, cy))
660  TABTEST( align * tab, tabcount, "\t\t", MAKELONG(tab*2, cy))
661  TABTEST( align * tab, tabcount, "\tx\t", MAKELONG(tab*2, cy))
662  TABTEST( align * tab, tabcount, "x\tx", MAKELONG(tab+cx, cy))
663  TABTEST( align * tab, tabcount, "xx\tx", MAKELONG(tab+cx, cy))
664  TABTEST( align * tab, tabcount, "xxx\tx", MAKELONG(tab+cx, cy))
665  TABTEST( align * tab, tabcount, "xxxx\tx", MAKELONG(t>0 ? tab + cx : 2*tab+cx, cy))
666  TABTEST( align * tab, tabcount, "xxxxx\tx", MAKELONG(2*tab+cx, cy))
667  }
668  }
669  align=-1;
670  for( t=-1; t<=1; t++) { /* slightly adjust the 4 char tabstop, to
671  catch the one off errors */
672  tab = (cx *4 + t);
673  /* test the special case tabcount =1 and the general array (8) of tabs */
674  for( tabcount = 1; tabcount <= 8; tabcount +=7) {
675  TABTEST( align * tab, tabcount, "\t", MAKELONG(tab, cy))
676  TABTEST( align * tab, tabcount, "xxx\t", MAKELONG(tab, cy))
677  TABTEST( align * tab, tabcount, "\tx", MAKELONG(tab, cy))
678  TABTEST( align * tab, tabcount, "\t\t", MAKELONG(tab*2, cy))
679  TABTEST( align * tab, tabcount, "\tx\t", MAKELONG(tab*2, cy))
680  TABTEST( align * tab, tabcount, "x\tx", MAKELONG(tab, cy))
681  TABTEST( align * tab, tabcount, "xx\tx", MAKELONG(tab, cy))
682  TABTEST( align * tab, tabcount, "xxx\tx", MAKELONG(4 * cx >= tab ? 2*tab :tab, cy))
683  TABTEST( align * tab, tabcount, "xxxx\tx", MAKELONG(2*tab, cy))
684  TABTEST( align * tab, tabcount, "xxxxx\tx", MAKELONG(2*tab, cy))
685  }
686  }
687 
688  ReleaseDC( hwnd, hdc );
689  DestroyWindow( hwnd );
690 }
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:570
#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:570
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:613

Referenced by START_TEST().