1*c2c66affSColin Finck /*
2*c2c66affSColin Finck  * DrawText tests
3*c2c66affSColin Finck  *
4*c2c66affSColin Finck  * Copyright (c) 2004 Zach Gorman
5*c2c66affSColin Finck  * Copyright 2007,2016 Dmitry Timoshkov
6*c2c66affSColin Finck  *
7*c2c66affSColin Finck  * This library is free software; you can redistribute it and/or
8*c2c66affSColin Finck  * modify it under the terms of the GNU Lesser General Public
9*c2c66affSColin Finck  * License as published by the Free Software Foundation; either
10*c2c66affSColin Finck  * version 2.1 of the License, or (at your option) any later version.
11*c2c66affSColin Finck  *
12*c2c66affSColin Finck  * This library is distributed in the hope that it will be useful,
13*c2c66affSColin Finck  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14*c2c66affSColin Finck  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15*c2c66affSColin Finck  * Lesser General Public License for more details.
16*c2c66affSColin Finck  *
17*c2c66affSColin Finck  * You should have received a copy of the GNU Lesser General Public
18*c2c66affSColin Finck  * License along with this library; if not, write to the Free Software
19*c2c66affSColin Finck  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20*c2c66affSColin Finck  */
21*c2c66affSColin Finck 
22*c2c66affSColin Finck #include <assert.h>
23*c2c66affSColin Finck 
24*c2c66affSColin Finck #include "wine/test.h"
25*c2c66affSColin Finck #include "winbase.h"
26*c2c66affSColin Finck #include "wingdi.h"
27*c2c66affSColin Finck #include "winuser.h"
28*c2c66affSColin Finck #include "winerror.h"
29*c2c66affSColin Finck #include "winnls.h"
30*c2c66affSColin Finck 
31*c2c66affSColin Finck #define MODIFIED(rect) (rect.left == 10 && rect.right != 100 && rect.top == 10 && rect.bottom != 100)
32*c2c66affSColin Finck #define EMPTY(rect) (rect.left == rect.right && rect.bottom == rect.top)
33*c2c66affSColin Finck 
34*c2c66affSColin Finck static void test_DrawTextCalcRect(void)
35*c2c66affSColin Finck {
36*c2c66affSColin Finck     HWND hwnd;
37*c2c66affSColin Finck     HDC hdc;
38*c2c66affSColin Finck     HFONT hFont, hOldFont;
39*c2c66affSColin Finck     LOGFONTA lf;
40*c2c66affSColin Finck     static CHAR text[] = "Example text for testing DrawText in "
41*c2c66affSColin Finck       "MM_HIENGLISH mode";
42*c2c66affSColin Finck     static WCHAR textW[] = {'W','i','d','e',' ','c','h','a','r',' ',
43*c2c66affSColin Finck         's','t','r','i','n','g','\0'};
44*c2c66affSColin Finck     static CHAR emptystring[] = "";
45*c2c66affSColin Finck     static WCHAR emptystringW[] = { 0 };
46*c2c66affSColin Finck     static CHAR wordbreak_text[] = "line1 line2";
47*c2c66affSColin Finck     static WCHAR wordbreak_textW[] = {'l','i','n','e','1',' ','l','i','n','e','2',0};
48*c2c66affSColin Finck     static char tabstring[] = "one\ttwo";
49*c2c66affSColin Finck     INT textlen, textheight, heightcheck;
50*c2c66affSColin Finck     RECT rect = { 0, 0, 100, 0 }, rect2;
51*c2c66affSColin Finck     BOOL ret;
52*c2c66affSColin Finck     DRAWTEXTPARAMS dtp;
53*c2c66affSColin Finck     BOOL conform_xp = TRUE;
54*c2c66affSColin Finck 
55*c2c66affSColin Finck     /* Initialization */
56*c2c66affSColin Finck     hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP,
57*c2c66affSColin Finck                            0, 0, 200, 200, 0, 0, 0, NULL);
58*c2c66affSColin Finck     ok(hwnd != 0, "CreateWindowExA error %u\n", GetLastError());
59*c2c66affSColin Finck     hdc = GetDC(hwnd);
60*c2c66affSColin Finck     ok(hdc != 0, "GetDC error %u\n", GetLastError());
61*c2c66affSColin Finck     trace("hdc %p\n", hdc);
62*c2c66affSColin Finck     textlen = lstrlenA(text);
63*c2c66affSColin Finck 
64*c2c66affSColin Finck     /* LOGFONT initialization */
65*c2c66affSColin Finck     memset(&lf, 0, sizeof(lf));
66*c2c66affSColin Finck     lf.lfCharSet = ANSI_CHARSET;
67*c2c66affSColin Finck     lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
68*c2c66affSColin Finck     lf.lfWeight = FW_DONTCARE;
69*c2c66affSColin Finck     lf.lfHeight = 0; /* mapping mode dependent */
70*c2c66affSColin Finck     lf.lfQuality = DEFAULT_QUALITY;
71*c2c66affSColin Finck     lstrcpyA(lf.lfFaceName, "Arial");
72*c2c66affSColin Finck 
73*c2c66affSColin Finck     /* DrawText in MM_HIENGLISH with DT_CALCRECT */
74*c2c66affSColin Finck     SetMapMode(hdc, MM_HIENGLISH);
75*c2c66affSColin Finck     lf.lfHeight = 100 * 9 / 72; /* 9 point */
76*c2c66affSColin Finck     hFont = CreateFontIndirectA(&lf);
77*c2c66affSColin Finck     ok(hFont != 0, "CreateFontIndirectA error %u\n",
78*c2c66affSColin Finck        GetLastError());
79*c2c66affSColin Finck     hOldFont = SelectObject(hdc, hFont);
80*c2c66affSColin Finck 
81*c2c66affSColin Finck     textheight = DrawTextA(hdc, text, textlen, &rect, DT_CALCRECT |
82*c2c66affSColin Finck        DT_EXTERNALLEADING | DT_WORDBREAK | DT_NOCLIP | DT_LEFT |
83*c2c66affSColin Finck        DT_NOPREFIX);
84*c2c66affSColin Finck     ok( textheight, "DrawTextA error %u\n", GetLastError());
85*c2c66affSColin Finck 
86*c2c66affSColin Finck     trace("MM_HIENGLISH rect.bottom %d\n", rect.bottom);
87*c2c66affSColin Finck     ok(rect.bottom < 0, "In MM_HIENGLISH, DrawText with "
88*c2c66affSColin Finck        "DT_CALCRECT should return a negative rectangle bottom. "
89*c2c66affSColin Finck        "(bot=%d)\n", rect.bottom);
90*c2c66affSColin Finck 
91*c2c66affSColin Finck     SelectObject(hdc, hOldFont);
92*c2c66affSColin Finck     ret = DeleteObject(hFont);
93*c2c66affSColin Finck     ok( ret, "DeleteObject error %u\n", GetLastError());
94*c2c66affSColin Finck 
95*c2c66affSColin Finck 
96*c2c66affSColin Finck     /* DrawText in MM_TEXT with DT_CALCRECT */
97*c2c66affSColin Finck     SetMapMode(hdc, MM_TEXT);
98*c2c66affSColin Finck     lf.lfHeight = -MulDiv(9, GetDeviceCaps(hdc,
99*c2c66affSColin Finck        LOGPIXELSY), 72); /* 9 point */
100*c2c66affSColin Finck     hFont = CreateFontIndirectA(&lf);
101*c2c66affSColin Finck     ok(hFont != 0, "CreateFontIndirectA error %u\n",
102*c2c66affSColin Finck        GetLastError());
103*c2c66affSColin Finck     hOldFont = SelectObject(hdc, hFont);
104*c2c66affSColin Finck 
105*c2c66affSColin Finck     textheight = DrawTextA(hdc, text, textlen, &rect, DT_CALCRECT |
106*c2c66affSColin Finck        DT_EXTERNALLEADING | DT_WORDBREAK | DT_NOCLIP | DT_LEFT |
107*c2c66affSColin Finck        DT_NOPREFIX);
108*c2c66affSColin Finck     ok( textheight, "DrawTextA error %u\n", GetLastError());
109*c2c66affSColin Finck 
110*c2c66affSColin Finck     trace("MM_TEXT rect.bottom %d\n", rect.bottom);
111*c2c66affSColin Finck     ok(rect.bottom > 0, "In MM_TEXT, DrawText with DT_CALCRECT "
112*c2c66affSColin Finck        "should return a positive rectangle bottom. (bot=%d)\n",
113*c2c66affSColin Finck        rect.bottom);
114*c2c66affSColin Finck 
115*c2c66affSColin Finck     /* empty or null text should in some cases calc an empty rectangle */
116*c2c66affSColin Finck 
117*c2c66affSColin Finck     SetRect( &rect, 10,10, 100, 100);
118*c2c66affSColin Finck     heightcheck = textheight = DrawTextExA(hdc, text, 0, &rect, DT_CALCRECT, NULL );
119*c2c66affSColin Finck     ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
120*c2c66affSColin Finck         "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
121*c2c66affSColin Finck     ok(textheight==0,"Got textheight from DrawTextExA\n");
122*c2c66affSColin Finck 
123*c2c66affSColin Finck     SetRect( &rect, 10,10, 100, 100);
124*c2c66affSColin Finck     textheight = DrawTextA(hdc, text, 0, &rect, DT_CALCRECT);
125*c2c66affSColin Finck     ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
126*c2c66affSColin Finck         "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
127*c2c66affSColin Finck     if (conform_xp)
128*c2c66affSColin Finck         ok(textheight==0,"Got textheight from DrawTextA\n");
129*c2c66affSColin Finck     ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
130*c2c66affSColin Finck 
131*c2c66affSColin Finck     SetRect( &rect, 10,10, 100, 100);
132*c2c66affSColin Finck     SetLastError( 0);
133*c2c66affSColin Finck     heightcheck = textheight = DrawTextExA(hdc, emptystring, -1, &rect, DT_CALCRECT, NULL );
134*c2c66affSColin Finck     ok(EMPTY(rect), "rectangle should be empty got %s\n", wine_dbgstr_rect(&rect));
135*c2c66affSColin Finck     ok(textheight!=0,"Failed to get textheight from DrawTextExA\n");
136*c2c66affSColin Finck 
137*c2c66affSColin Finck     SetRect( &rect, 10,10, 100, 100);
138*c2c66affSColin Finck     textheight = DrawTextA(hdc, emptystring, -1, &rect, DT_CALCRECT);
139*c2c66affSColin Finck     ok(EMPTY(rect), "rectangle should be empty got %s\n", wine_dbgstr_rect(&rect));
140*c2c66affSColin Finck     ok(textheight!=0,"Failed to get textheight from DrawTextA\n");
141*c2c66affSColin Finck     ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
142*c2c66affSColin Finck 
143*c2c66affSColin Finck     SetRect( &rect, 10,10, 100, 100);
144*c2c66affSColin Finck     SetLastError( 0);
145*c2c66affSColin Finck     heightcheck = textheight = DrawTextExA(hdc, NULL, -1, &rect, DT_CALCRECT, NULL );
146*c2c66affSColin Finck     ok(EMPTY(rect), "rectangle should be empty got %s\n", wine_dbgstr_rect(&rect));
147*c2c66affSColin Finck     if (!textheight) /* Windows NT 4 */
148*c2c66affSColin Finck     {
149*c2c66affSColin Finck         if (conform_xp)
150*c2c66affSColin Finck             win_skip("XP conformity failed, skipping XP tests. Probably winNT\n");
151*c2c66affSColin Finck         conform_xp = FALSE;
152*c2c66affSColin Finck     }
153*c2c66affSColin Finck     else
154*c2c66affSColin Finck         ok(textheight!=0,"Failed to get textheight from DrawTextExA\n");
155*c2c66affSColin Finck 
156*c2c66affSColin Finck     SetRect( &rect, 10,10, 100, 100);
157*c2c66affSColin Finck     textheight = DrawTextA(hdc, NULL, -1, &rect, DT_CALCRECT);
158*c2c66affSColin Finck     ok(EMPTY(rect), "rectangle should be empty got %s\n", wine_dbgstr_rect(&rect));
159*c2c66affSColin Finck     if (conform_xp)
160*c2c66affSColin Finck         ok(textheight!=0,"Failed to get textheight from DrawTextA\n");
161*c2c66affSColin Finck     ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
162*c2c66affSColin Finck 
163*c2c66affSColin Finck     SetRect( &rect, 10,10, 100, 100);
164*c2c66affSColin Finck     heightcheck = textheight = DrawTextExA(hdc, NULL, 0, &rect, DT_CALCRECT, NULL );
165*c2c66affSColin Finck     ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
166*c2c66affSColin Finck         "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
167*c2c66affSColin Finck     if (conform_xp)
168*c2c66affSColin Finck         ok(textheight==0,"Got textheight from DrawTextExA\n");
169*c2c66affSColin Finck 
170*c2c66affSColin Finck     SetRect( &rect, 10,10, 100, 100);
171*c2c66affSColin Finck     textheight = DrawTextA(hdc, NULL, 0, &rect, DT_CALCRECT);
172*c2c66affSColin Finck     ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
173*c2c66affSColin Finck         "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
174*c2c66affSColin Finck     if (conform_xp)
175*c2c66affSColin Finck         ok(textheight==0,"Got textheight from DrawTextA\n");
176*c2c66affSColin Finck     ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
177*c2c66affSColin Finck 
178*c2c66affSColin Finck     /* DT_SINGLELINE tests */
179*c2c66affSColin Finck 
180*c2c66affSColin Finck     SetRect( &rect, 10,10, 100, 100);
181*c2c66affSColin Finck     heightcheck = textheight = DrawTextExA(hdc, text, 0, &rect, DT_CALCRECT|DT_SINGLELINE, NULL );
182*c2c66affSColin Finck     ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
183*c2c66affSColin Finck         "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
184*c2c66affSColin Finck     if (conform_xp)
185*c2c66affSColin Finck         ok(textheight==0,"Got textheight from DrawTextExA\n");
186*c2c66affSColin Finck 
187*c2c66affSColin Finck     SetRect( &rect, 10,10, 100, 100);
188*c2c66affSColin Finck     textheight = DrawTextA(hdc, text, 0, &rect, DT_CALCRECT|DT_SINGLELINE);
189*c2c66affSColin Finck     ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
190*c2c66affSColin Finck         "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
191*c2c66affSColin Finck     if (conform_xp)
192*c2c66affSColin Finck         ok(textheight==0,"Got textheight from DrawTextA\n");
193*c2c66affSColin Finck     ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
194*c2c66affSColin Finck 
195*c2c66affSColin Finck     SetRect( &rect, 10,10, 100, 100);
196*c2c66affSColin Finck     SetLastError( 0);
197*c2c66affSColin Finck     heightcheck = textheight = DrawTextExA(hdc, emptystring, -1, &rect, DT_CALCRECT|DT_SINGLELINE, NULL );
198*c2c66affSColin Finck     ok(!EMPTY(rect) && MODIFIED(rect), "rectangle should be modified got %s\n",
199*c2c66affSColin Finck        wine_dbgstr_rect(&rect));
200*c2c66affSColin Finck     ok(textheight!=0,"Failed to get textheight from DrawTextExA\n");
201*c2c66affSColin Finck 
202*c2c66affSColin Finck     SetRect( &rect, 10,10, 100, 100);
203*c2c66affSColin Finck     textheight = DrawTextA(hdc, emptystring, -1, &rect, DT_CALCRECT|DT_SINGLELINE);
204*c2c66affSColin Finck     ok(!EMPTY(rect) && MODIFIED (rect), "rectangle should be modified got %s\n",
205*c2c66affSColin Finck        wine_dbgstr_rect(&rect));
206*c2c66affSColin Finck     ok(textheight!=0,"Failed to get textheight from DrawTextA\n");
207*c2c66affSColin Finck     ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
208*c2c66affSColin Finck 
209*c2c66affSColin Finck     SetRect( &rect, 10,10, 100, 100);
210*c2c66affSColin Finck     SetLastError( 0);
211*c2c66affSColin Finck     heightcheck = textheight = DrawTextExA(hdc, NULL, -1, &rect, DT_CALCRECT|DT_SINGLELINE, NULL );
212*c2c66affSColin Finck     ok(!EMPTY(rect) && MODIFIED(rect), "rectangle should be modified got %s\n",
213*c2c66affSColin Finck        wine_dbgstr_rect(&rect));
214*c2c66affSColin Finck     if (conform_xp)
215*c2c66affSColin Finck         ok(textheight!=0,"Failed to get textheight from DrawTextExA\n");
216*c2c66affSColin Finck 
217*c2c66affSColin Finck     SetRect( &rect, 10,10, 100, 100);
218*c2c66affSColin Finck     textheight = DrawTextA(hdc, NULL, -1, &rect, DT_CALCRECT|DT_SINGLELINE);
219*c2c66affSColin Finck     ok(!EMPTY(rect) && MODIFIED(rect), "rectangle should be modified got %s\n",
220*c2c66affSColin Finck        wine_dbgstr_rect(&rect));
221*c2c66affSColin Finck     if (conform_xp)
222*c2c66affSColin Finck         ok(textheight!=0,"Failed to get textheight from DrawTextA\n");
223*c2c66affSColin Finck     ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
224*c2c66affSColin Finck 
225*c2c66affSColin Finck     SetRect( &rect, 10,10, 100, 100);
226*c2c66affSColin Finck     heightcheck = textheight = DrawTextExA(hdc, NULL, 0, &rect, DT_CALCRECT|DT_SINGLELINE, NULL );
227*c2c66affSColin Finck     ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
228*c2c66affSColin Finck         "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
229*c2c66affSColin Finck     if (conform_xp)
230*c2c66affSColin Finck         ok(textheight==0,"Got textheight from DrawTextExA\n");
231*c2c66affSColin Finck 
232*c2c66affSColin Finck     SetRect( &rect, 10,10, 100, 100);
233*c2c66affSColin Finck     textheight = DrawTextA(hdc, NULL, 0, &rect, DT_CALCRECT|DT_SINGLELINE);
234*c2c66affSColin Finck     ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
235*c2c66affSColin Finck         "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
236*c2c66affSColin Finck     if (conform_xp)
237*c2c66affSColin Finck         ok(textheight==0,"Got textheight from DrawTextA\n");
238*c2c66affSColin Finck     ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
239*c2c66affSColin Finck 
240*c2c66affSColin Finck     /* further tests with  0 count, NULL and empty strings */
241*c2c66affSColin Finck     heightcheck = textheight = DrawTextA(hdc, text, 0, &rect, 0);
242*c2c66affSColin Finck     if (conform_xp)
243*c2c66affSColin Finck         ok(textheight==0,"Got textheight from DrawTextA\n");
244*c2c66affSColin Finck     textheight = DrawTextExA(hdc, text, 0, &rect, 0, NULL );
245*c2c66affSColin Finck     if (conform_xp)
246*c2c66affSColin Finck         ok(textheight==0,"Got textheight from DrawTextExA\n");
247*c2c66affSColin Finck     ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
248*c2c66affSColin Finck     heightcheck = textheight = DrawTextA(hdc, emptystring, 0, &rect, 0);
249*c2c66affSColin Finck     if (conform_xp)
250*c2c66affSColin Finck         ok(textheight==0,"Got textheight from DrawTextA\n");
251*c2c66affSColin Finck     textheight = DrawTextExA(hdc, emptystring, 0, &rect, 0, NULL );
252*c2c66affSColin Finck     if (conform_xp)
253*c2c66affSColin Finck         ok(textheight==0,"Got textheight from DrawTextExA\n");
254*c2c66affSColin Finck     ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
255*c2c66affSColin Finck     heightcheck = textheight = DrawTextA(hdc, NULL, 0, &rect, 0);
256*c2c66affSColin Finck     if (conform_xp)
257*c2c66affSColin Finck         ok(textheight==0,"Got textheight from DrawTextA\n");
258*c2c66affSColin Finck     textheight = DrawTextExA(hdc, NULL, 0, &rect, 0, NULL );
259*c2c66affSColin Finck     if (conform_xp)
260*c2c66affSColin Finck         ok(textheight==0,"Got textheight from DrawTextExA\n");
261*c2c66affSColin Finck     ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
262*c2c66affSColin Finck     heightcheck = textheight = DrawTextA(hdc, emptystring, -1, &rect, 0);
263*c2c66affSColin Finck     ok(textheight!=0,"Failed to get textheight from DrawTextA\n");
264*c2c66affSColin Finck     textheight = DrawTextExA(hdc, emptystring, -1, &rect, 0, NULL );
265*c2c66affSColin Finck     ok(textheight!=0,"Failed to get textheight from DrawTextExA\n");
266*c2c66affSColin Finck     ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
267*c2c66affSColin Finck     heightcheck = textheight = DrawTextA(hdc, NULL, -1, &rect, 0);
268*c2c66affSColin Finck     if (conform_xp)
269*c2c66affSColin Finck         ok(textheight!=0,"Failed to get textheight from DrawTextA\n");
270*c2c66affSColin Finck     textheight = DrawTextExA(hdc, NULL, -1, &rect, 0, NULL );
271*c2c66affSColin Finck     if (conform_xp)
272*c2c66affSColin Finck         ok(textheight!=0,"Failed to get textheight from DrawTextExA\n");
273*c2c66affSColin Finck     ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
274*c2c66affSColin Finck     heightcheck = textheight = DrawTextA(hdc, NULL, 10, &rect, 0);
275*c2c66affSColin Finck     ok(textheight==0,"Got textheight from DrawTextA\n");
276*c2c66affSColin Finck     textheight = DrawTextExA(hdc, NULL, 10, &rect, 0, NULL );
277*c2c66affSColin Finck     ok(textheight==0,"Got textheight from DrawTextA\n");
278*c2c66affSColin Finck     ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
279*c2c66affSColin Finck 
280*c2c66affSColin Finck 
281*c2c66affSColin Finck     /* invalid dtp size test */
282*c2c66affSColin Finck     dtp.cbSize = -1; /* Invalid */
283*c2c66affSColin Finck     dtp.uiLengthDrawn = 1337;
284*c2c66affSColin Finck     textheight = DrawTextExA(hdc, text, 0, &rect, 0, &dtp);
285*c2c66affSColin Finck     ok(textheight==0,"Got textheight from DrawTextExA\n");
286*c2c66affSColin Finck     ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn);
287*c2c66affSColin Finck     dtp.uiLengthDrawn = 1337;
288*c2c66affSColin Finck     textheight = DrawTextExA(hdc, emptystring, 0, &rect, 0, &dtp);
289*c2c66affSColin Finck     ok(textheight==0,"Got textheight from DrawTextExA\n");
290*c2c66affSColin Finck     ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn);
291*c2c66affSColin Finck     dtp.uiLengthDrawn = 1337;
292*c2c66affSColin Finck     textheight = DrawTextExA(hdc, NULL, 0, &rect, 0, &dtp);
293*c2c66affSColin Finck     ok(textheight==0,"Got textheight from DrawTextExA\n");
294*c2c66affSColin Finck     ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn);
295*c2c66affSColin Finck     dtp.uiLengthDrawn = 1337;
296*c2c66affSColin Finck     textheight = DrawTextExA(hdc, emptystring, -1, &rect, 0, &dtp);
297*c2c66affSColin Finck     ok(textheight==0,"Got textheight from DrawTextExA\n");
298*c2c66affSColin Finck     ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn);
299*c2c66affSColin Finck     dtp.uiLengthDrawn = 1337;
300*c2c66affSColin Finck     textheight = DrawTextExA(hdc, NULL, -1, &rect, 0, &dtp);
301*c2c66affSColin Finck     ok(textheight==0,"Got textheight from DrawTextExA\n");
302*c2c66affSColin Finck     ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn);
303*c2c66affSColin Finck 
304*c2c66affSColin Finck     /* Margin calculations */
305*c2c66affSColin Finck     dtp.cbSize = sizeof(dtp);
306*c2c66affSColin Finck     dtp.iLeftMargin = 0;
307*c2c66affSColin Finck     dtp.iRightMargin = 0;
308*c2c66affSColin Finck     SetRectEmpty(&rect);
309*c2c66affSColin Finck     DrawTextExA(hdc, text, -1, &rect, DT_CALCRECT, &dtp);
310*c2c66affSColin Finck     textlen = rect.right; /* Width without margin */
311*c2c66affSColin Finck     dtp.iLeftMargin = 8;
312*c2c66affSColin Finck     SetRectEmpty(&rect);
313*c2c66affSColin Finck     DrawTextExA(hdc, text, -1, &rect, DT_CALCRECT, &dtp);
314*c2c66affSColin Finck     ok(rect.right==dtp.iLeftMargin+textlen  ,"Incorrect left margin calculated  rc(%d,%d)\n", rect.left, rect.right);
315*c2c66affSColin Finck     dtp.iLeftMargin = 0;
316*c2c66affSColin Finck     dtp.iRightMargin = 8;
317*c2c66affSColin Finck     SetRectEmpty(&rect);
318*c2c66affSColin Finck     DrawTextExA(hdc, text, -1, &rect, DT_CALCRECT, &dtp);
319*c2c66affSColin Finck     ok(rect.right==dtp.iRightMargin+textlen  ,"Incorrect right margin calculated rc(%d,%d)\n", rect.left, rect.right);
320*c2c66affSColin Finck 
321*c2c66affSColin Finck     /* Wide char versions */
322*c2c66affSColin Finck     SetRect( &rect, 10,10, 100, 100);
323*c2c66affSColin Finck     SetLastError( 0);
324*c2c66affSColin Finck     heightcheck = textheight = DrawTextExW(hdc, textW, 0, &rect, DT_CALCRECT, NULL );
325*c2c66affSColin Finck     if( GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) {
326*c2c66affSColin Finck         ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
327*c2c66affSColin Finck             "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
328*c2c66affSColin Finck         ok(textheight!=0,"Failed to get textheight from DrawTextExW\n");
329*c2c66affSColin Finck 
330*c2c66affSColin Finck         SetRect( &rect, 10,10, 100, 100);
331*c2c66affSColin Finck         textheight = DrawTextW(hdc, textW, 0, &rect, DT_CALCRECT);
332*c2c66affSColin Finck         ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
333*c2c66affSColin Finck             "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
334*c2c66affSColin Finck         ok(textheight!=0,"Failed to get textheight from DrawTextW\n");
335*c2c66affSColin Finck         ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
336*c2c66affSColin Finck 
337*c2c66affSColin Finck         SetRect( &rect, 10,10, 100, 100);
338*c2c66affSColin Finck         heightcheck = textheight = DrawTextExW(hdc, emptystringW, -1, &rect, DT_CALCRECT, NULL );
339*c2c66affSColin Finck         ok(EMPTY(rect), "rectangle should be empty got %s\n", wine_dbgstr_rect(&rect));
340*c2c66affSColin Finck         ok(textheight!=0,"Failed to get textheight from DrawTextExW\n");
341*c2c66affSColin Finck 
342*c2c66affSColin Finck         SetRect( &rect, 10,10, 100, 100);
343*c2c66affSColin Finck         textheight = DrawTextW(hdc, emptystringW, -1, &rect, DT_CALCRECT);
344*c2c66affSColin Finck         ok(EMPTY(rect), "rectangle should be empty got %s\n", wine_dbgstr_rect(&rect));
345*c2c66affSColin Finck         ok(textheight!=0,"Failed to get textheight from DrawTextW\n");
346*c2c66affSColin Finck         ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
347*c2c66affSColin Finck 
348*c2c66affSColin Finck         SetRect( &rect, 10,10, 100, 100);
349*c2c66affSColin Finck         heightcheck = textheight = DrawTextExW(hdc, NULL, 0, &rect, DT_CALCRECT, NULL );
350*c2c66affSColin Finck         ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
351*c2c66affSColin Finck             "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
352*c2c66affSColin Finck         if (textheight) /* windows 2000 */
353*c2c66affSColin Finck         {
354*c2c66affSColin Finck             if (conform_xp)
355*c2c66affSColin Finck                 win_skip("XP conformity failed, skipping XP tests. Probably win 2000\n");
356*c2c66affSColin Finck             conform_xp = FALSE;
357*c2c66affSColin Finck         }
358*c2c66affSColin Finck         else
359*c2c66affSColin Finck             ok(textheight==0,"Got textheight from DrawTextExW\n");
360*c2c66affSColin Finck 
361*c2c66affSColin Finck         SetRect( &rect, 10,10, 100, 100);
362*c2c66affSColin Finck         textheight = DrawTextW(hdc, NULL, 0, &rect, DT_CALCRECT);
363*c2c66affSColin Finck         ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
364*c2c66affSColin Finck             "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
365*c2c66affSColin Finck         if (conform_xp)
366*c2c66affSColin Finck             ok(textheight==0,"Got textheight from DrawTextW\n");
367*c2c66affSColin Finck         ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
368*c2c66affSColin Finck 
369*c2c66affSColin Finck         if (conform_xp) {
370*c2c66affSColin Finck             /* Crashes on NT4 */
371*c2c66affSColin Finck             SetRect( &rect, 10,10, 100, 100);
372*c2c66affSColin Finck             heightcheck = textheight = DrawTextExW(hdc, NULL, -1, &rect, DT_CALCRECT, NULL );
373*c2c66affSColin Finck             ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
374*c2c66affSColin Finck                 "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
375*c2c66affSColin Finck             ok(textheight==0,"Got textheight from DrawTextExW\n");
376*c2c66affSColin Finck 
377*c2c66affSColin Finck             SetRect( &rect, 10,10, 100, 100);
378*c2c66affSColin Finck             textheight = DrawTextW(hdc, NULL, -1, &rect, DT_CALCRECT);
379*c2c66affSColin Finck             ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
380*c2c66affSColin Finck                 "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
381*c2c66affSColin Finck             ok(textheight==0,"Got textheight from DrawTextW\n");
382*c2c66affSColin Finck             ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
383*c2c66affSColin Finck         }
384*c2c66affSColin Finck 
385*c2c66affSColin Finck 
386*c2c66affSColin Finck         /* DT_SINGLELINE tests */
387*c2c66affSColin Finck 
388*c2c66affSColin Finck         heightcheck = textheight = DrawTextExW(hdc, textW, 0, &rect, DT_CALCRECT|DT_SINGLELINE, NULL );
389*c2c66affSColin Finck         ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
390*c2c66affSColin Finck             "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
391*c2c66affSColin Finck         ok(textheight!=0,"Failed to get textheight from DrawTextExW\n");
392*c2c66affSColin Finck 
393*c2c66affSColin Finck         SetRect( &rect, 10,10, 100, 100);
394*c2c66affSColin Finck         textheight = DrawTextW(hdc, textW, 0, &rect, DT_CALCRECT|DT_SINGLELINE);
395*c2c66affSColin Finck         ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
396*c2c66affSColin Finck             "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
397*c2c66affSColin Finck         ok(textheight!=0,"Failed to get textheight from DrawTextW\n");
398*c2c66affSColin Finck         ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
399*c2c66affSColin Finck 
400*c2c66affSColin Finck         SetRect( &rect, 10,10, 100, 100);
401*c2c66affSColin Finck         heightcheck = textheight = DrawTextExW(hdc, emptystringW, -1, &rect, DT_CALCRECT|DT_SINGLELINE, NULL );
402*c2c66affSColin Finck         ok(!EMPTY(rect) && MODIFIED(rect), "rectangle should be modified got %s\n",
403*c2c66affSColin Finck            wine_dbgstr_rect(&rect));
404*c2c66affSColin Finck         ok(textheight!=0,"Failed to get textheight from DrawTextExW\n");
405*c2c66affSColin Finck 
406*c2c66affSColin Finck         SetRect( &rect, 10,10, 100, 100);
407*c2c66affSColin Finck         textheight = DrawTextW(hdc, emptystringW, -1, &rect, DT_CALCRECT|DT_SINGLELINE);
408*c2c66affSColin Finck         ok(!EMPTY(rect) && MODIFIED(rect), "rectangle should be modified got %s\n",
409*c2c66affSColin Finck            wine_dbgstr_rect(&rect));
410*c2c66affSColin Finck         ok(textheight!=0,"Failed to get textheight from DrawTextW\n");
411*c2c66affSColin Finck         ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
412*c2c66affSColin Finck 
413*c2c66affSColin Finck         if (conform_xp) {
414*c2c66affSColin Finck             /* Crashes on NT4 */
415*c2c66affSColin Finck             SetRect( &rect, 10,10, 100, 100);
416*c2c66affSColin Finck             heightcheck = textheight = DrawTextExW(hdc, NULL, -1, &rect, DT_CALCRECT|DT_SINGLELINE, NULL );
417*c2c66affSColin Finck             ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
418*c2c66affSColin Finck                 "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
419*c2c66affSColin Finck             ok(textheight==0,"Got textheight from DrawTextExW\n");
420*c2c66affSColin Finck 
421*c2c66affSColin Finck             SetRect( &rect, 10,10, 100, 100);
422*c2c66affSColin Finck             textheight = DrawTextW(hdc, NULL, -1, &rect, DT_CALCRECT|DT_SINGLELINE);
423*c2c66affSColin Finck             ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
424*c2c66affSColin Finck                 "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
425*c2c66affSColin Finck             ok(textheight==0,"Got textheight from DrawTextW\n");
426*c2c66affSColin Finck             ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
427*c2c66affSColin Finck         }
428*c2c66affSColin Finck 
429*c2c66affSColin Finck         SetRect( &rect, 10,10, 100, 100);
430*c2c66affSColin Finck         heightcheck = textheight = DrawTextExW(hdc, NULL, 0, &rect, DT_CALCRECT|DT_SINGLELINE, NULL );
431*c2c66affSColin Finck         ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
432*c2c66affSColin Finck             "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
433*c2c66affSColin Finck         if (conform_xp)
434*c2c66affSColin Finck             ok(textheight==0,"Got textheight from DrawTextExW\n");
435*c2c66affSColin Finck 
436*c2c66affSColin Finck         SetRect( &rect, 10,10, 100, 100);
437*c2c66affSColin Finck         textheight = DrawTextW(hdc, NULL, 0, &rect, DT_CALCRECT|DT_SINGLELINE);
438*c2c66affSColin Finck         ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
439*c2c66affSColin Finck             "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
440*c2c66affSColin Finck         if (conform_xp)
441*c2c66affSColin Finck             ok(textheight==0,"Got textheight from DrawTextW\n");
442*c2c66affSColin Finck         ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
443*c2c66affSColin Finck 
444*c2c66affSColin Finck         /* further tests with NULL and empty strings */
445*c2c66affSColin Finck         heightcheck = textheight = DrawTextW(hdc, textW, 0, &rect, 0);
446*c2c66affSColin Finck         ok(textheight!=0,"Failed to get textheight from DrawTextW\n");
447*c2c66affSColin Finck         textheight = DrawTextExW(hdc, textW, 0, &rect, 0, NULL );
448*c2c66affSColin Finck         ok(textheight!=0,"Failed to get textheight from DrawTextExW\n");
449*c2c66affSColin Finck         ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
450*c2c66affSColin Finck         heightcheck = textheight = DrawTextW(hdc, emptystringW, 0, &rect, 0);
451*c2c66affSColin Finck         ok(textheight!=0,"Failed to get textheight from DrawTextW\n");
452*c2c66affSColin Finck         textheight = DrawTextExW(hdc, emptystringW, 0, &rect, 0, NULL );
453*c2c66affSColin Finck         ok(textheight!=0,"Failed to get textheight from DrawTextExW\n");
454*c2c66affSColin Finck         ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
455*c2c66affSColin Finck         heightcheck = textheight = DrawTextW(hdc, NULL, 0, &rect, 0);
456*c2c66affSColin Finck         if (conform_xp)
457*c2c66affSColin Finck             ok(textheight==0,"Got textheight from DrawTextW\n");
458*c2c66affSColin Finck         textheight = DrawTextExW(hdc, NULL, 0, &rect, 0, NULL );
459*c2c66affSColin Finck         if (conform_xp)
460*c2c66affSColin Finck             ok(textheight==0,"Got textheight from DrawTextExW\n");
461*c2c66affSColin Finck         ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
462*c2c66affSColin Finck         heightcheck = textheight = DrawTextW(hdc, emptystringW, -1, &rect, 0);
463*c2c66affSColin Finck         ok(textheight!=0,"Failed to get textheight from DrawTextW\n");
464*c2c66affSColin Finck         textheight = DrawTextExW(hdc, emptystringW, -1, &rect, 0, NULL );
465*c2c66affSColin Finck         ok(textheight!=0,"Failed to get textheight from DrawTextExW\n");
466*c2c66affSColin Finck         ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
467*c2c66affSColin Finck         if (conform_xp) {
468*c2c66affSColin Finck             /* Crashes on NT4 */
469*c2c66affSColin Finck             heightcheck = textheight = DrawTextW(hdc, NULL, -1, &rect, 0);
470*c2c66affSColin Finck             ok(textheight==0,"Got textheight from DrawTextW\n");
471*c2c66affSColin Finck             textheight = DrawTextExW(hdc, NULL, -1, &rect, 0, NULL );
472*c2c66affSColin Finck             ok(textheight==0,"Got textheight from DrawTextExW\n");
473*c2c66affSColin Finck             ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
474*c2c66affSColin Finck             heightcheck = textheight = DrawTextW(hdc, NULL, 10, &rect, 0);
475*c2c66affSColin Finck             ok(textheight==0,"Got textheight from DrawTextW\n");
476*c2c66affSColin Finck             textheight = DrawTextExW(hdc, NULL, 10, &rect, 0, NULL );
477*c2c66affSColin Finck             ok(textheight==0,"Got textheight from DrawTextW\n");
478*c2c66affSColin Finck             ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
479*c2c66affSColin Finck         }
480*c2c66affSColin Finck 
481*c2c66affSColin Finck         dtp.cbSize = -1; /* Invalid */
482*c2c66affSColin Finck         dtp.uiLengthDrawn = 1337;
483*c2c66affSColin Finck         textheight = DrawTextExW(hdc, textW, 0, &rect, 0, &dtp);
484*c2c66affSColin Finck         ok(textheight!=0,"Failed to get textheight from DrawTextExW\n");
485*c2c66affSColin Finck         ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn);
486*c2c66affSColin Finck         dtp.uiLengthDrawn = 1337;
487*c2c66affSColin Finck         textheight = DrawTextExW(hdc, emptystringW, 0, &rect, 0, &dtp);
488*c2c66affSColin Finck         if (conform_xp)
489*c2c66affSColin Finck             ok(textheight==0,"Got textheight from DrawTextExW\n");
490*c2c66affSColin Finck         ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn);
491*c2c66affSColin Finck         dtp.uiLengthDrawn = 1337;
492*c2c66affSColin Finck         textheight = DrawTextExW(hdc, NULL, 0, &rect, 0, &dtp);
493*c2c66affSColin Finck         if (conform_xp)
494*c2c66affSColin Finck             ok(textheight==0,"Got textheight from DrawTextExW\n");
495*c2c66affSColin Finck         ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn);
496*c2c66affSColin Finck         dtp.uiLengthDrawn = 1337;
497*c2c66affSColin Finck         textheight = DrawTextExW(hdc, emptystringW, -1, &rect, 0, &dtp);
498*c2c66affSColin Finck         ok(textheight==0,"Got textheight from DrawTextExW\n");
499*c2c66affSColin Finck         ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn);
500*c2c66affSColin Finck         if (conform_xp) {
501*c2c66affSColin Finck             /* Crashes on NT4 */
502*c2c66affSColin Finck             dtp.uiLengthDrawn = 1337;
503*c2c66affSColin Finck             textheight = DrawTextExW(hdc, NULL, -1, &rect, 0, &dtp);
504*c2c66affSColin Finck             ok(textheight==0,"Got textheight from DrawTextExW\n");
505*c2c66affSColin Finck             ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn);
506*c2c66affSColin Finck         }
507*c2c66affSColin Finck     }
508*c2c66affSColin Finck 
509*c2c66affSColin Finck     /* More test cases from bug 12226 */
510*c2c66affSColin Finck     SetRectEmpty(&rect);
511*c2c66affSColin Finck     textheight = DrawTextA(hdc, emptystring, -1, &rect, DT_CALCRECT | DT_LEFT | DT_SINGLELINE);
512*c2c66affSColin Finck     ok(textheight, "DrawTextA error %u\n", GetLastError());
513*c2c66affSColin Finck     ok(0 == rect.left, "expected 0, got %d\n", rect.left);
514*c2c66affSColin Finck     ok(0 == rect.right, "expected 0, got %d\n", rect.right);
515*c2c66affSColin Finck     ok(0 == rect.top, "expected 0, got %d\n", rect.top);
516*c2c66affSColin Finck     ok(rect.bottom, "rect.bottom should not be 0\n");
517*c2c66affSColin Finck 
518*c2c66affSColin Finck     SetRectEmpty(&rect);
519*c2c66affSColin Finck     textheight = DrawTextW(hdc, emptystringW, -1, &rect, DT_CALCRECT | DT_LEFT | DT_SINGLELINE);
520*c2c66affSColin Finck     if (!textheight && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
521*c2c66affSColin Finck     {
522*c2c66affSColin Finck         win_skip( "DrawTextW not implemented\n" );
523*c2c66affSColin Finck     }
524*c2c66affSColin Finck     else
525*c2c66affSColin Finck     {
526*c2c66affSColin Finck         ok(textheight, "DrawTextW error %u\n", GetLastError());
527*c2c66affSColin Finck         ok(0 == rect.left, "expected 0, got %d\n", rect.left);
528*c2c66affSColin Finck         ok(0 == rect.right, "expected 0, got %d\n", rect.right);
529*c2c66affSColin Finck         ok(0 == rect.top, "expected 0, got %d\n", rect.top);
530*c2c66affSColin Finck         ok(rect.bottom, "rect.bottom should not be 0\n");
531*c2c66affSColin Finck     }
532*c2c66affSColin Finck 
533*c2c66affSColin Finck     SetRect(&rect, 0, 0, 1, 1);
534*c2c66affSColin Finck     heightcheck = DrawTextA(hdc, wordbreak_text, -1, &rect, DT_CALCRECT);
535*c2c66affSColin Finck     SetRect(&rect, 0, 0, 1, 1);
536*c2c66affSColin Finck     textheight = DrawTextA(hdc, wordbreak_text, -1, &rect, DT_CALCRECT | DT_WORDBREAK);
537*c2c66affSColin Finck     ok(textheight == heightcheck * 2, "Got unexpected textheight %d, expected %d.\n",
538*c2c66affSColin Finck        textheight, heightcheck * 2);
539*c2c66affSColin Finck     SetRect(&rect, 0, 0, 1, 1);
540*c2c66affSColin Finck     textheight = DrawTextA(hdc, wordbreak_text, -1, &rect, DT_CALCRECT | DT_WORDBREAK | DT_EDITCONTROL);
541*c2c66affSColin Finck     ok(textheight >= heightcheck * 6, "Got unexpected textheight %d, expected at least %d.\n",
542*c2c66affSColin Finck        textheight, heightcheck * 6);
543*c2c66affSColin Finck 
544*c2c66affSColin Finck     SetRect(&rect, 0, 0, 1, 1);
545*c2c66affSColin Finck     heightcheck = DrawTextW(hdc, wordbreak_textW, -1, &rect, DT_CALCRECT);
546*c2c66affSColin Finck     SetRect(&rect, 0, 0, 1, 1);
547*c2c66affSColin Finck     textheight = DrawTextW(hdc, wordbreak_textW, -1, &rect, DT_CALCRECT | DT_WORDBREAK);
548*c2c66affSColin Finck     ok(textheight == heightcheck * 2, "Got unexpected textheight %d, expected %d.\n",
549*c2c66affSColin Finck        textheight, heightcheck * 2);
550*c2c66affSColin Finck     SetRect(&rect, 0, 0, 1, 1);
551*c2c66affSColin Finck     textheight = DrawTextW(hdc, wordbreak_textW, -1, &rect, DT_CALCRECT | DT_WORDBREAK | DT_EDITCONTROL);
552*c2c66affSColin Finck     ok(textheight >= heightcheck * 6, "Got unexpected textheight %d, expected at least %d.\n",
553*c2c66affSColin Finck        textheight, heightcheck * 6);
554*c2c66affSColin Finck 
555*c2c66affSColin Finck     /* DT_TABSTOP | DT_EXPANDTABS tests */
556*c2c66affSColin Finck     SetRect( &rect, 0,0, 10, 10);
557*c2c66affSColin Finck     textheight = DrawTextA(hdc, tabstring, -1, &rect, DT_TABSTOP | DT_EXPANDTABS );
558*c2c66affSColin Finck     ok(textheight >= heightcheck, "Got unexpected textheight %d\n", textheight);
559*c2c66affSColin Finck 
560*c2c66affSColin Finck     SetRect( &rect, 0,0, 10, 10);
561*c2c66affSColin Finck     memset(&dtp, 0, sizeof(dtp));
562*c2c66affSColin Finck     dtp.cbSize = sizeof(dtp);
563*c2c66affSColin Finck     textheight = DrawTextExA(hdc, tabstring, -1, &rect, DT_CALCRECT, &dtp);
564*c2c66affSColin Finck     ok(textheight >= heightcheck, "Got unexpected textheight %d\n", textheight);
565*c2c66affSColin Finck     ok(dtp.iTabLength == 0, "invalid dtp.iTabLength = %i\n",dtp.iTabLength);
566*c2c66affSColin Finck 
567*c2c66affSColin Finck     SetRect( &rect2, 0,0, 10, 10);
568*c2c66affSColin Finck     memset(&dtp, 0, sizeof(dtp));
569*c2c66affSColin Finck     dtp.cbSize = sizeof(dtp);
570*c2c66affSColin Finck     textheight = DrawTextExA(hdc, tabstring, -1, &rect2, DT_CALCRECT | DT_TABSTOP | DT_EXPANDTABS, &dtp);
571*c2c66affSColin Finck     ok(textheight >= heightcheck, "Got unexpected textheight %d\n", textheight);
572*c2c66affSColin Finck     ok(dtp.iTabLength == 0, "invalid dtp.iTabLength = %i\n",dtp.iTabLength);
573*c2c66affSColin Finck     ok(rect.left == rect2.left && rect.right != rect2.right && rect.top == rect2.top && rect.bottom == rect2.bottom,
574*c2c66affSColin Finck        "incorrect rect %s rect2 %s\n", wine_dbgstr_rect(&rect), wine_dbgstr_rect(&rect2));
575*c2c66affSColin Finck 
576*c2c66affSColin Finck     SetRect( &rect, 0,0, 10, 10);
577*c2c66affSColin Finck     memset(&dtp, 0, sizeof(dtp));
578*c2c66affSColin Finck     dtp.cbSize = sizeof(dtp);
579*c2c66affSColin Finck     dtp.iTabLength = 8;
580*c2c66affSColin Finck     textheight = DrawTextExA(hdc, tabstring, -1, &rect, DT_CALCRECT | DT_TABSTOP | DT_EXPANDTABS, &dtp);
581*c2c66affSColin Finck     ok(textheight >= heightcheck, "Got unexpected textheight %d\n", textheight);
582*c2c66affSColin Finck     ok(dtp.iTabLength == 8, "invalid dtp.iTabLength = %i\n",dtp.iTabLength);
583*c2c66affSColin Finck     ok(rect.left == rect2.left, "unexpected value %d, got %d\n", rect.left, rect2.left);
584*c2c66affSColin Finck     /* XP, 2003 appear to not give the same values. */
585*c2c66affSColin Finck     ok(rect.right == rect2.right || broken(rect.right > rect2.right), "unexpected value %d, got %d\n",rect.right, rect2.right);
586*c2c66affSColin Finck     ok(rect.top == rect2.top, "unexpected value %d, got %d\n", rect.top, rect2.top);
587*c2c66affSColin Finck     ok(rect.bottom == rect2.bottom , "unexpected value %d, got %d\n", rect.bottom, rect2.bottom);
588*c2c66affSColin Finck 
589*c2c66affSColin Finck 
590*c2c66affSColin Finck     SelectObject(hdc, hOldFont);
591*c2c66affSColin Finck     ret = DeleteObject(hFont);
592*c2c66affSColin Finck     ok( ret, "DeleteObject error %u\n", GetLastError());
593*c2c66affSColin Finck 
594*c2c66affSColin Finck     /* Clean up */
595*c2c66affSColin Finck     ret = ReleaseDC(hwnd, hdc);
596*c2c66affSColin Finck     ok( ret, "ReleaseDC error %u\n", GetLastError());
597*c2c66affSColin Finck     ret = DestroyWindow(hwnd);
598*c2c66affSColin Finck     ok( ret, "DestroyWindow error %u\n", GetLastError());
599*c2c66affSColin Finck }
600*c2c66affSColin Finck 
601*c2c66affSColin Finck /* replace tabs by \t */
602*c2c66affSColin Finck static void strfmt( const char *str, char *strout)
603*c2c66affSColin Finck {
604*c2c66affSColin Finck     unsigned int i,j ;
605*c2c66affSColin Finck     for(i=0,j=0;i<=strlen(str);i++,j++)
606*c2c66affSColin Finck         if((strout[j]=str[i])=='\t') {
607*c2c66affSColin Finck             strout[j++]='\\';
608*c2c66affSColin Finck             strout[j]='t';
609*c2c66affSColin Finck         }
610*c2c66affSColin Finck }
611*c2c66affSColin Finck 
612*c2c66affSColin Finck 
613*c2c66affSColin Finck #define TABTEST( tabval, tabcount, string, _exp) \
614*c2c66affSColin Finck { int i; char strdisp[64];\
615*c2c66affSColin Finck     for(i=0;i<8;i++) tabs[i]=(i+1)*(tabval); \
616*c2c66affSColin Finck     extent = GetTabbedTextExtentA( hdc, string, strlen( string), (tabcount), tabs); \
617*c2c66affSColin Finck     strfmt( string, strdisp); \
618*c2c66affSColin Finck  /*   trace( "Extent is %08lx\n", extent); */\
619*c2c66affSColin Finck     ok( extent == _exp, "Test case \"%s\". Text extent is 0x%x, expected 0x%x tab %d tabcount %d\n", \
620*c2c66affSColin Finck         strdisp, extent, _exp, tabval, tabcount); \
621*c2c66affSColin Finck } \
622*c2c66affSColin Finck 
623*c2c66affSColin Finck 
624*c2c66affSColin Finck static void test_TabbedText(void)
625*c2c66affSColin Finck {
626*c2c66affSColin Finck     HWND hwnd;
627*c2c66affSColin Finck     HDC hdc;
628*c2c66affSColin Finck     BOOL ret;
629*c2c66affSColin Finck     TEXTMETRICA tm;
630*c2c66affSColin Finck     DWORD extent;
631*c2c66affSColin Finck     INT tabs[8], cx, cy, tab, tabcount,t,align;
632*c2c66affSColin Finck 
633*c2c66affSColin Finck     /* Initialization */
634*c2c66affSColin Finck     hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP,
635*c2c66affSColin Finck                            0, 0, 200, 200, 0, 0, 0, NULL);
636*c2c66affSColin Finck     ok(hwnd != 0, "CreateWindowExA error %u\n", GetLastError());
637*c2c66affSColin Finck     hdc = GetDC(hwnd);
638*c2c66affSColin Finck     ok(hdc != 0, "GetDC error %u\n", GetLastError());
639*c2c66affSColin Finck 
640*c2c66affSColin Finck     ret = GetTextMetricsA( hdc, &tm);
641*c2c66affSColin Finck     ok( ret, "GetTextMetrics error %u\n", GetLastError());
642*c2c66affSColin Finck 
643*c2c66affSColin Finck     extent = GetTabbedTextExtentA( hdc, "x", 0, 1, tabs);
644*c2c66affSColin Finck     ok( extent == 0, "GetTabbedTextExtentA returned non-zero on nCount == 0\n");
645*c2c66affSColin Finck 
646*c2c66affSColin Finck     extent = GetTabbedTextExtentA( hdc, "x", 1, 1, tabs);
647*c2c66affSColin Finck     cx = LOWORD( extent);
648*c2c66affSColin Finck     cy = HIWORD( extent);
649*c2c66affSColin Finck     trace( "cx is %d cy is %d\n", cx, cy);
650*c2c66affSColin Finck 
651*c2c66affSColin Finck     align=1;
652*c2c66affSColin Finck     for( t=-1; t<=1; t++) { /* slightly adjust the 4 char tabstop, to
653*c2c66affSColin Finck                                catch the one off errors */
654*c2c66affSColin Finck         tab =  (cx *4 + t);
655*c2c66affSColin Finck         /* test the special case tabcount =1 and the general array (80 of tabs */
656*c2c66affSColin Finck         for( tabcount = 1; tabcount <= 8; tabcount +=7) {
657*c2c66affSColin Finck             TABTEST( align * tab, tabcount, "\t", MAKELONG(tab, cy))
658*c2c66affSColin Finck             TABTEST( align * tab, tabcount, "xxx\t", MAKELONG(tab, cy))
659*c2c66affSColin Finck             TABTEST( align * tab, tabcount, "\tx", MAKELONG(tab+cx, cy))
660*c2c66affSColin Finck             TABTEST( align * tab, tabcount, "\t\t", MAKELONG(tab*2, cy))
661*c2c66affSColin Finck             TABTEST( align * tab, tabcount, "\tx\t", MAKELONG(tab*2, cy))
662*c2c66affSColin Finck             TABTEST( align * tab, tabcount, "x\tx", MAKELONG(tab+cx, cy))
663*c2c66affSColin Finck             TABTEST( align * tab, tabcount, "xx\tx", MAKELONG(tab+cx, cy))
664*c2c66affSColin Finck             TABTEST( align * tab, tabcount, "xxx\tx", MAKELONG(tab+cx, cy))
665*c2c66affSColin Finck             TABTEST( align * tab, tabcount, "xxxx\tx", MAKELONG(t>0 ? tab + cx : 2*tab+cx, cy))
666*c2c66affSColin Finck             TABTEST( align * tab, tabcount, "xxxxx\tx", MAKELONG(2*tab+cx, cy))
667*c2c66affSColin Finck         }
668*c2c66affSColin Finck     }
669*c2c66affSColin Finck     align=-1;
670*c2c66affSColin Finck     for( t=-1; t<=1; t++) { /* slightly adjust the 4 char tabstop, to
671*c2c66affSColin Finck                                catch the one off errors */
672*c2c66affSColin Finck         tab =  (cx *4 + t);
673*c2c66affSColin Finck         /* test the special case tabcount =1 and the general array (8) of tabs */
674*c2c66affSColin Finck         for( tabcount = 1; tabcount <= 8; tabcount +=7) {
675*c2c66affSColin Finck             TABTEST( align * tab, tabcount, "\t", MAKELONG(tab, cy))
676*c2c66affSColin Finck             TABTEST( align * tab, tabcount, "xxx\t", MAKELONG(tab, cy))
677*c2c66affSColin Finck             TABTEST( align * tab, tabcount, "\tx", MAKELONG(tab, cy))
678*c2c66affSColin Finck             TABTEST( align * tab, tabcount, "\t\t", MAKELONG(tab*2, cy))
679*c2c66affSColin Finck             TABTEST( align * tab, tabcount, "\tx\t", MAKELONG(tab*2, cy))
680*c2c66affSColin Finck             TABTEST( align * tab, tabcount, "x\tx", MAKELONG(tab, cy))
681*c2c66affSColin Finck             TABTEST( align * tab, tabcount, "xx\tx", MAKELONG(tab, cy))
682*c2c66affSColin Finck             TABTEST( align * tab, tabcount, "xxx\tx", MAKELONG(4 * cx >= tab ? 2*tab :tab, cy))
683*c2c66affSColin Finck             TABTEST( align * tab, tabcount, "xxxx\tx", MAKELONG(2*tab, cy))
684*c2c66affSColin Finck             TABTEST( align * tab, tabcount, "xxxxx\tx", MAKELONG(2*tab, cy))
685*c2c66affSColin Finck         }
686*c2c66affSColin Finck     }
687*c2c66affSColin Finck 
688*c2c66affSColin Finck     ReleaseDC( hwnd, hdc );
689*c2c66affSColin Finck     DestroyWindow( hwnd );
690*c2c66affSColin Finck }
691*c2c66affSColin Finck 
692*c2c66affSColin Finck static void test_DrawState(void)
693*c2c66affSColin Finck {
694*c2c66affSColin Finck     static const char text[] = "Sample text string";
695*c2c66affSColin Finck     HWND hwnd;
696*c2c66affSColin Finck     HDC hdc;
697*c2c66affSColin Finck     BOOL ret;
698*c2c66affSColin Finck 
699*c2c66affSColin Finck     hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP,
700*c2c66affSColin Finck                            0, 0, 200, 200, 0, 0, 0, NULL);
701*c2c66affSColin Finck     assert(hwnd);
702*c2c66affSColin Finck 
703*c2c66affSColin Finck     hdc = GetDC(hwnd);
704*c2c66affSColin Finck     assert(hdc);
705*c2c66affSColin Finck 
706*c2c66affSColin Finck     SetLastError(0xdeadbeef);
707*c2c66affSColin Finck     ret = DrawStateA(hdc, GetStockObject(DKGRAY_BRUSH), NULL, (LPARAM)text, strlen(text),
708*c2c66affSColin Finck                     0, 0, 10, 10, DST_TEXT);
709*c2c66affSColin Finck     ok(ret, "DrawState error %u\n", GetLastError());
710*c2c66affSColin Finck 
711*c2c66affSColin Finck     SetLastError(0xdeadbeef);
712*c2c66affSColin Finck     ret = DrawStateA(hdc, GetStockObject(DKGRAY_BRUSH), NULL, (LPARAM)text, 0,
713*c2c66affSColin Finck                     0, 0, 10, 10, DST_TEXT);
714*c2c66affSColin Finck     ok(ret, "DrawState error %u\n", GetLastError());
715*c2c66affSColin Finck 
716*c2c66affSColin Finck     SetLastError(0xdeadbeef);
717*c2c66affSColin Finck     ret = DrawStateA(hdc, GetStockObject(DKGRAY_BRUSH), NULL, 0, strlen(text),
718*c2c66affSColin Finck                     0, 0, 10, 10, DST_TEXT);
719*c2c66affSColin Finck     ok(!ret || broken(ret) /* win98 */, "DrawState succeeded\n");
720*c2c66affSColin Finck     ok(GetLastError() == 0xdeadbeef, "not expected error %u\n", GetLastError());
721*c2c66affSColin Finck 
722*c2c66affSColin Finck     SetLastError(0xdeadbeef);
723*c2c66affSColin Finck     ret = DrawStateA(hdc, GetStockObject(DKGRAY_BRUSH), NULL, 0, 0,
724*c2c66affSColin Finck                     0, 0, 10, 10, DST_TEXT);
725*c2c66affSColin Finck     ok(!ret || broken(ret) /* win98 */, "DrawState succeeded\n");
726*c2c66affSColin Finck     ok(GetLastError() == 0xdeadbeef, "not expected error %u\n", GetLastError());
727*c2c66affSColin Finck 
728*c2c66affSColin Finck     ReleaseDC(hwnd, hdc);
729*c2c66affSColin Finck     DestroyWindow(hwnd);
730*c2c66affSColin Finck }
731*c2c66affSColin Finck 
732*c2c66affSColin Finck static void test_CharToOem_OemToChar(void)
733*c2c66affSColin Finck {
734*c2c66affSColin Finck     static const WCHAR helloWorldW[] = {'H','e','l','l','o',' ','W','o','r','l','d',0};
735*c2c66affSColin Finck     static const WCHAR emptyW[] = {0};
736*c2c66affSColin Finck     static const char helloWorld[] = "Hello World";
737*c2c66affSColin Finck     static const struct
738*c2c66affSColin Finck     {
739*c2c66affSColin Finck         BOOL src, dst, ret;
740*c2c66affSColin Finck     }
741*c2c66affSColin Finck     tests[] =
742*c2c66affSColin Finck     {
743*c2c66affSColin Finck         { FALSE, FALSE, FALSE },
744*c2c66affSColin Finck         { TRUE,  FALSE, FALSE },
745*c2c66affSColin Finck         { FALSE, TRUE,  FALSE },
746*c2c66affSColin Finck         { TRUE,  TRUE,  TRUE  },
747*c2c66affSColin Finck     };
748*c2c66affSColin Finck     BOOL ret;
749*c2c66affSColin Finck     int i;
750*c2c66affSColin Finck     char oem;
751*c2c66affSColin Finck     WCHAR uni, expect;
752*c2c66affSColin Finck 
753*c2c66affSColin Finck     for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
754*c2c66affSColin Finck     {
755*c2c66affSColin Finck         const char *expected = tests[i].ret ? helloWorld : "";
756*c2c66affSColin Finck         const char *src = tests[i].src ? helloWorld : NULL;
757*c2c66affSColin Finck         char buf[64], *dst = tests[i].dst ? buf : NULL;
758*c2c66affSColin Finck 
759*c2c66affSColin Finck         memset(buf, 0, sizeof(buf));
760*c2c66affSColin Finck         ret = CharToOemA(src, dst);
761*c2c66affSColin Finck         ok(ret == tests[i].ret, "test %d: expected %d, got %d\n", i, tests[i].ret, ret);
762*c2c66affSColin Finck         ok(!strcmp(buf, expected), "test %d: got '%s'\n", i, buf);
763*c2c66affSColin Finck 
764*c2c66affSColin Finck         memset(buf, 0, sizeof(buf));
765*c2c66affSColin Finck         ret = CharToOemBuffA(src, dst, sizeof(helloWorld));
766*c2c66affSColin Finck         ok(ret == tests[i].ret, "test %d: expected %d, got %d\n", i, tests[i].ret, ret);
767*c2c66affSColin Finck         ok(!strcmp(buf, expected), "test %d: got '%s'\n", i, buf);
768*c2c66affSColin Finck 
769*c2c66affSColin Finck         memset(buf, 0, sizeof(buf));
770*c2c66affSColin Finck         ret = OemToCharA(src, dst);
771*c2c66affSColin Finck         ok(ret == tests[i].ret, "test %d: expected %d, got %d\n", i, tests[i].ret, ret);
772*c2c66affSColin Finck         ok(!strcmp(buf, expected), "test %d: got '%s'\n", i, buf);
773*c2c66affSColin Finck 
774*c2c66affSColin Finck         memset(buf, 0, sizeof(buf));
775*c2c66affSColin Finck         ret = OemToCharBuffA(src, dst, sizeof(helloWorld));
776*c2c66affSColin Finck         ok(ret == tests[i].ret, "test %d: expected %d, got %d\n", i, tests[i].ret, ret);
777*c2c66affSColin Finck         ok(!strcmp(buf, expected), "test %d: got '%s'\n", i, buf);
778*c2c66affSColin Finck     }
779*c2c66affSColin Finck 
780*c2c66affSColin Finck     for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
781*c2c66affSColin Finck     {
782*c2c66affSColin Finck         const char *expected = tests[i].ret ? helloWorld : "";
783*c2c66affSColin Finck         const WCHAR *src = tests[i].src ? helloWorldW : NULL;
784*c2c66affSColin Finck         char buf[64], *dst = tests[i].dst ? buf : NULL;
785*c2c66affSColin Finck 
786*c2c66affSColin Finck         memset(buf, 0, sizeof(buf));
787*c2c66affSColin Finck         ret = CharToOemW(src, dst);
788*c2c66affSColin Finck         ok(ret == tests[i].ret, "test %d: expected %d, got %d\n", i, tests[i].ret, ret);
789*c2c66affSColin Finck         ok(!strcmp(buf, expected), "test %d: got '%s'\n", i, buf);
790*c2c66affSColin Finck 
791*c2c66affSColin Finck         memset(buf, 0, sizeof(buf));
792*c2c66affSColin Finck         ret = CharToOemBuffW(src, dst, sizeof(helloWorldW)/sizeof(WCHAR));
793*c2c66affSColin Finck         ok(ret == tests[i].ret, "test %d: expected %d, got %d\n", i, tests[i].ret, ret);
794*c2c66affSColin Finck         ok(!strcmp(buf, expected), "test %d: got '%s'\n", i, buf);
795*c2c66affSColin Finck     }
796*c2c66affSColin Finck 
797*c2c66affSColin Finck     for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
798*c2c66affSColin Finck     {
799*c2c66affSColin Finck         const WCHAR *expected = tests[i].ret ? helloWorldW : emptyW;
800*c2c66affSColin Finck         const char *src = tests[i].src ? helloWorld : NULL;
801*c2c66affSColin Finck         WCHAR buf[64], *dst = tests[i].dst ? buf : NULL;
802*c2c66affSColin Finck 
803*c2c66affSColin Finck         memset(buf, 0, sizeof(buf));
804*c2c66affSColin Finck         ret = OemToCharW(src, dst);
805*c2c66affSColin Finck         ok(ret == tests[i].ret, "test %d: expected %d, got %d\n", i, tests[i].ret, ret);
806*c2c66affSColin Finck         ok(!lstrcmpW(buf, expected), "test %d: got '%s'\n", i, wine_dbgstr_w(buf));
807*c2c66affSColin Finck 
808*c2c66affSColin Finck         memset(buf, 0, sizeof(buf));
809*c2c66affSColin Finck         ret = OemToCharBuffW(src, dst, sizeof(helloWorld));
810*c2c66affSColin Finck         ok(ret == tests[i].ret, "test %d: expected %d, got %d\n", i, tests[i].ret, ret);
811*c2c66affSColin Finck         ok(!lstrcmpW(buf, expected), "test %d: got '%s'\n", i, wine_dbgstr_w(buf));
812*c2c66affSColin Finck     }
813*c2c66affSColin Finck 
814*c2c66affSColin Finck     for (i = 0; i < 0x100; i++)
815*c2c66affSColin Finck     {
816*c2c66affSColin Finck         oem = i;
817*c2c66affSColin Finck         ret = OemToCharBuffW( &oem, &uni, 1 );
818*c2c66affSColin Finck         ok( ret, "%02x: returns FALSE\n", i );
819*c2c66affSColin Finck         MultiByteToWideChar( CP_OEMCP, MB_PRECOMPOSED | MB_USEGLYPHCHARS, &oem, 1, &expect, 1 );
820*c2c66affSColin Finck         ok( uni == expect, "%02x: got %04x expected %04x\n", i, uni, expect );
821*c2c66affSColin Finck     }
822*c2c66affSColin Finck }
823*c2c66affSColin Finck 
824*c2c66affSColin Finck START_TEST(text)
825*c2c66affSColin Finck {
826*c2c66affSColin Finck     test_TabbedText();
827*c2c66affSColin Finck     test_DrawTextCalcRect();
828*c2c66affSColin Finck     test_DrawState();
829*c2c66affSColin Finck     test_CharToOem_OemToChar();
830*c2c66affSColin Finck }
831